Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема реализации IXmlSerializable.ReadXML, Проблемы с десериализацией xml-файла 
V
    Опции темы
Лен
Дата 20.1.2009, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 20.1.2009

Репутация: нет
Всего: нет



Есть Xml-документ приблизительно следующей структуры:
Код

<RootElement with SomeAttributes>
  <NodeType1 with SomeAttributes>
  <NodeType1 with SomeAttributes>
  ...
  <NodeType1 with SomeAttributes>
  <NodeType2 with SomeAttributes>
  <NodeType2 with SomeAttributes>
  ...
  <NodeType2 with SomeAttributes>
</RootElement with SomeAttributes>

Каждый узел NodeType1 и NodeType2 - сам по себе разветвлённое деревья с кучей потомков и аттрибутов.
Объект, в который десериализуется данный файл, поддерживает интерфейс IXmlSerializable.

Вопрос: как должен выглядеть код метода ReadXml объекта, чтобы все узлы NodeType1 и NodeType2 были корректно вычитаны? 
xmlReader.ReadToFollowing("NodeType1") - вычитывает все узлы NodeType1, но после этого читать узлы NodeType2 становится невозможным. xmlReader.ReadToNextSibling("NodeType1")  - вычитывает все узлы NodeType1, но попытка после этого так же читать узлы NodeType2 оканчивается исключением.
PM MAIL   Вверх
mihryak
Дата 20.1.2009, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



Код

        public class NodeType1
        {
            public string Value = Guid.NewGuid().ToString();
        }

        public class NodeType2
        {
            public string Value = Guid.NewGuid().ToString();
        }

        public class Root : IXmlSerializable
        {
            public List<NodeType1> Nodes1 = new List<NodeType1> { new NodeType1(), new NodeType1() };
            public List<NodeType2> Nodes2 = new List<NodeType2> { new NodeType2(), new NodeType2() };

            public XmlSchema GetSchema()
            {
                return null;
            }

            public void ReadXml(XmlReader reader)
            {
                Nodes1.Clear();
                Nodes2.Clear();

                if (reader.ReadToFollowing("RootElement"))
                {
                    while (reader.Read())
                    {
                        switch (reader.Name)
                        {
                            case "NodeType1":
                                NodeType1 node1 = new NodeType1();
                                node1.Value = reader["Value"];
                                Nodes1.Add(node1);
                                break;

                            case "NodeType2":
                                NodeType2 node2 = new NodeType2();
                                node2.Value = reader["Value"];
                                Nodes2.Add(node2);
                                break;
                        }
                    }
                }
            }

            public void WriteXml(XmlWriter writer)
            {
                writer.WriteStartElement("RootElement");

                foreach (NodeType1 type1 in Nodes1)
                {
                    writer.WriteStartElement("NodeType1");
                    writer.WriteAttributeString("Value", type1.Value);
                    writer.WriteEndElement();
                }

                foreach (NodeType2 type2 in Nodes2)
                {
                    writer.WriteStartElement("NodeType2");
                    writer.WriteAttributeString("Value", type2.Value);
                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
            }
        }

        static void Main(string[] args)
        {
            Root root = new Root();
            using (Stream stream = new MemoryStream())
            {
                XmlSerializer serializer = new XmlSerializer(typeof (Root));
                serializer.Serialize(stream, root);
                stream.Position = 0;
                root = (Root) serializer.Deserialize(stream);
            }
        }

попробуй как-нибудь в этом духе
PM MAIL ICQ   Вверх
Лен
Дата 21.1.2009, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 20.1.2009

Репутация: нет
Всего: нет



Спасибо, mihryak. Вопрос, конечно, не решился, но я нашёл, в какую сторону копать. Полный правильный код выглядит так:
Код

        public class NodeType1 : IXmlSerializable
        {
            ...
        }

        public class NodeType2 : IXmlSerializable
        {
            ...
        }

        public class Root : IXmlSerializable
        {
            public List<NodeType1> Nodes1 = new List<NodeType1>();
            public List<NodeType2> Nodes2 = new List<NodeType2>();

            public string Property1;
            public string Property2;
            ...

            ...

            public void ReadXml(XmlReader reader)
            {
                Property1 = reader.GetAttribute("attr1");
                Property2 = reader.GetAttribute("attr2");
                ...

                Nodes1.Clear();
                Nodes2.Clear();

                if (!reader.ReadSubtree().IsEmptyElement)
                {
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element)
                           switch (reader.Name)
                           {
                               case "NodeType1":
                                   NodeType1 node1 = new NodeType1();
                                   node1.ReadXml(reader);
                                   Nodes1.Add(node1);
                                   break;

                               case "NodeType2":
                                   NodeType2 node2 = new NodeType2();
                                   node2.ReadXml(reader);
                                   Nodes2.Add(node2);
                                   break;
                           }
                        else if (reader.Name == "RootElement")
                           break;
                    }
                }
            }

            public void WriteXml(XmlWriter writer)
            {
                writer.WriteAttributeString("attr1", Property1);
                writer.WriteAttributeString("attr2", Property2);
                ...

                foreach (NodeType1 type1 in Nodes1)
                {
                    writer.WriteStartElement("NodeType1");
                    type1.WriteXml(writer);
                    writer.WriteEndElement();
                }

                foreach (NodeType2 type2 in Nodes2)
                {
                    writer.WriteStartElement("NodeType2");
                    type2.WriteXml(writer);
                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
            }
        }

Ещё: NodeTypeX.Read/WriteXml должны реализовываться подобным образом - тогда схема 100% работает корректно.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0925 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.