Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Наследство XML / 12 сообщений из 12, страница 1 из 1
20.10.2003, 20:46
    #32299094
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Всем здрасьте. А особенно тебе уважаемый All.
Прошу минутку внимания и толику терпения.
Вопрос собственно в наследовании и расширении XML классов, а конкретнее XmlNode который естественно потребует XmlDocument для нормальной работы.

В чем Задача:
Хочу перегрузить некоторые бинарные операторы для нодов а именно : <>= и иже сними.
В чем Проблема: При попытке создания наследника XMlNode получаю ошибку
"'System.Xml.XmlNode.XmlNode()' is inaccessible due to its protection level" и никакого наследства со всеми его перегруженными радостями. Не знаю как там у него с уровнем защиты, но судя по всему публичного конструктора класс XmlNode действительно не имеет, в этом то и загвоздка.

В связи с вышеизложенным вопрос:
Можно ли и если да то "КАК?" решить Проблему для получения удовольствия от решения Задачи?
Сталкивался ли кто из уважаемых коллег с подобной казуистикой? Какой возможен workaround?

Спасибо.
...
Рейтинг: 0 / 0
20.10.2003, 22:09
    #32299124
hDrummer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
А Магнуса ближе к ночи терзал страшный дух XML'a ;)
...
Рейтинг: 0 / 0
20.10.2003, 22:52
    #32299143
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Он меня терзает уже давненько со времен нелегкого 10 октября, когда я вступил в бой "За Сравнение". Стороны, обменявшись предварительными ударами отошли на исходны позиции.\r
Мною же, было решено сделать подкоп и взять врага изнутри, чем и занялся.\r
Сейчас заканчиваю предварительную стадию, а именно сортировку нодов и детей оных.\r
\r
Не такой уж он и страшный, энтот дух, если приглядеться :).\r
\r
Подскажешь чего нить из секретного оружия?\r
\r
\r
Magnus
...
Рейтинг: 0 / 0
21.10.2003, 14:19
    #32299904
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Знач так. Враг сдал позиции и трусливо бежит(кто бы сомневался, ха!). Наследство я таки получил. И по заведенным, еще древними славянами, правилам, публикую решение дабы помочь в нелекгом бою братьям по оружию.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
using System;
using System.Xml;


namespace XmlEx
{


    public class XmlDocumentEx : XmlDocument 
    //создаем новый класс документа с базой на XmlDocument
    {
        internal XmlDocumentEx():base()  /*вызываем его базовый конструктор, если хотите, можете перегрузить  другой.*/ 
        {}


	 /*А тут начинается интересное. Дабы почуствовать всю силу нашей
 Перезагрузки(матрицу помните? так вот, тут все не  так! :) ) и получить Наши 
новые элементы по всему документу, перегружаем метод CreateElement 
который собственно и 	используется самим классом при загрузке 
документа или создании новых нодов.*/ 

        public override XmlElement CreateElement(string prefix, string localname, string nsURI) 
        {
	     /*создаем экземпляр нашего элемента передавая ему необходимые параметры*/ 	
            XmlElementEx elem = new XmlElementEx(prefix, localname, nsURI, this);
            return elem;
        }
          
    }


	 /*собственно расширение класса элемента. XMlnode наследовать 
НЕЛЬЗЯ, но можно наследовать класс от которого наследует 	ОН :), что и 
делаем вызывая внутренний конструктор с параметрами переданнымни от 
документа.*/ 

    public class XmlElementEx : XmlElement
    {
        internal XmlElementEx ( string prefix, string localname, string nsURI,
            XmlDocument doc ) : base( prefix, localname, nsURI, doc )
        {//сюда можете запихнуть свою инициализации, буде вам так угодно}

           
       
	 /* А вот и САМОЕ интересно, то к чему мы шли. Перегрузка 
необходимых операторов, в моем случае это бинарные операторы 
сравнения, в ваше может быть что угодно. Передаем оператору в 
качестве параметров два НАШИХ элемента производим 	необходимое 
сравнение(в данном случае только имена, но это тест) и возвращаем 
результат.*/ 
 
       public static bool operator <(XmlElementEx Node1 , XmlElementEx Node2)
        {
        if(Node1.LocalName.CompareTo(Node2.LocalName)< 0 )
            return true;
            return false;             
        }

	 /* еще одна интересна весЧ: бинарные операторы перегружаются парами, повтояем...*/ 

        public static  bool operator >(XmlElementEx Node1 , XmlElementEx Node2)
        {
            if(Node1.LocalName.CompareTo(Node2.LocalName)> 0 )
            return true;
            return false;
        
        }



	 /* а теперь небольшой тест, создаем экземпляр нашего документа с 
нашими нодами и вывводим в командную строку 	результат сравнения 
двух нодов. Обратите внимание> сравниваются обьекты, а в вызове 
перегруженного опереатора уже их 		имена.В данном примере для 
сравнения взят первый же Child от Рута и его ближний сосед.*/ 

    public class Test
    {
        public static void Main()
        {
        XmlDocumentEx MyDoc = new XmlDocumentEx();
        MyDoc.Load( "c:\\sample2.xml" );
        XmlElementEx Node1=(XmlElementEx) MyDoc.DocumentElement.FirstChild;
        XmlElementEx Node2=(XmlElementEx) MyDoc.DocumentElement.FirstChild.NextSibling;
        Console.Write(Node1<Node2);
        Console.Read();

	//наслаждаемся результатом :). Просто, не правда ли?     
        }
    }

}


Все.

Дрюм! Предлагаю занести это решение куда нить в Фак, не столько из моей природной сркомности и застенчивости сколько из заботы о ближних. Так как судя по всему у многих здешних обитателей серьезные проблемы с XML, вот мне к примеру, так никто и не ответил. Одобрям? :)

ЗЫ Если кому чего непонятно, прошу задавать вопросы докладчику пока он не ушел в запой или на работу. :)
...
Рейтинг: 0 / 0
21.10.2003, 15:08
    #32300008
Sizhik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Походу прийдется также расширять все(или только некоторые, в зависимости от структуры XML документа) классы производные от XmlNode и XmlLinkedNode.
...
Рейтинг: 0 / 0
21.10.2003, 15:50
    #32300101
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Sizhik писал:
Походу прийдется также расширять все(или только некоторые, в зависимости от структуры XML документа) классы производные от XmlNode и XmlLinkedNode.
Думаю не придется. Ведь в моем примере расширен не XmlNode а XmlElement от которого наследуют и нод и линкед нод. Т.е. они уже "мои". Не скажу что все теперь гладко, конечно нет. Подводные камни есть всегда. Майкрософт вообще не рекомендует наследовать классы ХМЛ и конкретно нод. Вот например, у меня в коде был использован нодлист, и т.к. он в принципе не является дочерним элементом документа то и возвращал он не "мои" ноды а обычные, тут уж надо бы перегрузить и ChildNodes, но пока обошелся простым конвертированием, хотя в идеале думаю сделать.
Конечно, смотреть надо уже по конкретному случаю, что расширять а что нет.
У меня цель была, перегрузить некоторые операторы и далее работать как обычно. Для нее подобный код вполне подходит. Это подкоп под XmlNode, не под сам документ.
...
Рейтинг: 0 / 0
21.10.2003, 16:20
    #32300153
Sizhik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Magnus23 писал:
...Ведь в моем примере расширен не XmlNode а XmlElement от которого наследуют и нод и линкед нод. Т.е. они уже "мои"...


Хм, странно, дока па .НЕТ-у отзывается о XmlElement в диаметрально противоположном направлении:
Код: plaintext
1.
2.
3.
4.
System.Object
   System.Xml.XmlNode
      System.Xml.XmlLinkedNode
         System.Xml.XmlElement

Код: plaintext
1.
2.
[C#]
public class XmlElement : XmlLinkedNode
...
Рейтинг: 0 / 0
21.10.2003, 16:38
    #32300183
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Действительно странно. Особенно если учесть что из невиртуальных методов у документа есть только CreateElement... который и был перегружен.
Хм...
Если верить доке(а придется) то в любом случае проблемы быть не должно, он наследник линкед нода а значит полностью совместим.
Кстати за время рабты с XML еще не разу напрямую не работал с классом линкед нод, поэтому в принципе не вижу препятствия. Думаю личше решать проблемы по мере их возникновения, потому как с такими темпами, ради нескольких перегрузок, скоро будем наследовать половину DOM'a :)


Magnus
...
Рейтинг: 0 / 0
22.10.2003, 12:09
    #32301187
Sizhik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Magnus23 писал:
Действительно странно. Особенно если учесть что из невиртуальных методов у документа есть только CreateElement... который и был перегружен.

Может я чего-то не понимаю, но в твоем примере как раз был переопределен виртуальный метод. К тому же в XmlDocument помимо CreateElement существует набор виртуальных методов CreateXXX которые вызываются при загрузке XML-я в XmlDocument(проверено посредством декомпилирования System.Xml.dll).

Теперь вернемся к проблеме наследования XmlNode. Проблема фактически не решаемая поскольку у XmlNode есть два internal конструктора(доступность лимитирована рамками текущего проэкта, в данном случае этот проэкт .NET Framework). С другой стороны, такая ситуация вполне понятна поскольку класс XmlNode не используется на прамую, а является базовым и содержит набор функциональности общей для всего набора классов более высокого уровня.

Возможным решением проблемы является наследование ряда классов более высокого уровня, как-то XmlElement, XmlText, XmlAttribute и т.д. Кол-во классов требуемых для наследования зависит от сложностью структуры используемого XML-я. Простой пример, имеем довольно таки тривиальный XML:
Код: plaintext
1.
<root><child attr= "attribute content" >child content</child></root>

Лоадим этот XML в XmlDocument, при этом на событие OnNodeInserted ставим обработчик и смотрим на тип вставляемых нод:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
	class Class1 {

		//Define the event handler.
		static void NodeInsertedHandler(Object src, XmlNodeChangedEventArgs args) {
			Console.WriteLine( "Node "  + args.Node.Name +  "("  + args.Node.NodeType +  ") inserted!!" );
		}

		[STAThread]
		static void Main(string[] args) {
			XmlDocument doc = new XmlDocument();
			doc.NodeInserted += new XmlNodeChangedEventHandler(Class1.NodeInsertedHandler);

			doc.Load( "e:\\test.xml" );
			Console.Read();
		}
	}

Node.NodeType фактичекски показывает какой из наследников XmlNode вставляется в XmlDocument.

В общем без переопределения половины DOM-а я так понимаю ничего не выйдет. :)
...
Рейтинг: 0 / 0
22.10.2003, 15:10
    #32301594
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Sizhik писал:Может я чего-то не понимаю, но в твоем примере как раз был переопределен виртуальный метод
Упс. Моя ошибка. Действительно, у меня был переопределен виртуальный метод. Тем не менее эыто работает, в моем примере, после загрузки, документ состоит именно из моих элементов и перегруженные операторы прекрасно работают.

Sizhik писал:
В общем без переопределения половины DOM-а я так понимаю ничего не выйдет. :)
Для глобального случая - да. Нужно расширять довольно много классов чтобы покрыть все. Нов моем конкретном случае вполне достаточно нодов. Эту часть я практически закончил. Все работает, только вот атрибут расширять поленился, да и не особо нужно было, сделал проседуркой. :)

Согласен, я сам сначала немного запутался в нем. Никогда не вникал глубоко в структуру. При ближайшем рассмотрении обнаружил: существует 2 не виртуальных CreateElement и несколько виртуальных CreateXXX, прямо относящихся к нашему вопросу.Мой - верхний.

Невиртуальные в конце с "new".

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
  public override XmlElement CreateElement(string prefix, string localName, string namespaceURI)
    {
        return null;
    }
    
    public override XmlNode CreateNode(XmlNodeType type, string name, string namespaceURI)
    {
        return null;
    }
    
    public override XmlNode CreateNode(string nodeTypeString, string name, string namespaceURI)
    {
        return null;
    }
    
    public override XmlNode CreateNode(XmlNodeType type, string prefix, string name, string namespaceURI)
    {
        return null;
    }
    
    public override XmlText CreateTextNode(string text)
    {
        return null;
    }
    
    public new XmlElement CreateElement(string name)
    {
        return null;
    }
    
    public new XmlElement CreateElement(string qualifiedName, string namespaceURI)
    {
        return null;
    }


Т.е. по идее переопределять нужно, действительно, последние два не виртуальных метода, чтобы получить контроль над остальными, так?
Но мой тоже работает, только для нодов и их детей. Значит сам документ использует именно этот метод? Кстати, впомнил почему я занялся именно им, эта инфа как раз с майкрософта, в их примере был переопределен именно этот, вот я и подумал что по логике он должен быть единственным не виртуалным. Опять парят мозги простым людям ? :)

Кстати, все эти операторы я выкопал с помощью одной хорошей тулзы :
Inherited Class Skeleton Generator. Генерирует он "так себе" но для просмотра внутренностей вполне годится :). Тулза фревая, где сам достал не помню, в гугле искал, ссылок валом, свободно скачивается.

Эх. Учиться нам еще и учиться. ПО крайней мере мне :)


Magnus
...
Рейтинг: 0 / 0
22.10.2003, 17:04
    #32301929
Sizhik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Для декомпилинга использую Anakrino . Выдает на 90% удобочитаемый C#-ский код.

Стек-трейс для лоада документа(если юзать декомпилер, поскольку XmlLoader приватный класс):
XmlDocument.Load(string)
XmlDocument.Load(XmlReader)
XmlLoader.Load(XmlDocument, XmlReader, bool)
XmlLoader.LoadDocSequence(XmlDocument)
XmlLoader.LoadCurrentNode() <- тебе нужна именно это функция, в ней вызываются CreateXXX методы XmlDocument-а

Magnus23 писал:
Эх. Учиться нам еще и учиться....

Согласен с тодой на все сто :)
...
Рейтинг: 0 / 0
22.10.2003, 18:14
    #32302081
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наследство XML
Есть у меня Anakrino, хорошая штука, полезная, но пока мало им пользовался, времени нет на изыски, все колбашу... :)
Значит ноды создаются вызовами из LoadCurrentNode? Надо будет глянуть.
Я с тим всем ковырянием нашел другой путь решения своей проблемы(ну эт всегда так :) ), без переопределения классов и операторов. Более удобный и компактный.
НО! Опыт полученный в результате данных подкопов весьма ценен :) Когда нить пригодится. Может и не нам :)

Magnus
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Наследство XML / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]