Десериализация XML в объект C #

Я пытаюсь преобразовать данные Xml в объект C #.

Мой класс C # выглядит примерно так:

Public Class XmlModel {
    public string NodeName { get; set; }
    public int NodeId { get; set; }
    public int ParentId { get; set; }
}

Я могу получить все узлы XML и создать список объекта. Вот мой код для получения узлов.

public List<XMLModel2> ProcessXml()
    {
        XMLRepository xr = new XMLRepository(new POCEntities());
        XmlDocument doc = new XmlDocument();
        var a = xr.GetXmlFileById(1);
        doc.LoadXml(a.XmlFile);
        XmlNode rootNode = doc.DocumentElement;
        GetChildNodeWithId(rootNode);
        return NodeList;

    }





    public void GetChildNodeWithId(XmlNode node)
    {
        AddNode(node);
         XmlNodeList children = node.ChildNodes;
        if (children != null)
        {
            for (int i = 0; i < children.Count; i++)
            {
                GetChildNodeWithId(children[i]);
            }

        }
    }



    public void AddNode(XmlNode node)
    {
            XMLModel xml = new XMLModel();
            xml.NodeName = node.Name;
            xml.NodeValue = node.Value;
            NodeList.Add(xml);
        } 

Теперь у меня возникла проблема с вставкой NodeId и ParentId, которые мои необходимые данные должны выглядеть так при преобразовании xml в

<parent>
   <child>
     <key> one </key>
     <key> two </key>
     <key> Three </key>
</child>
   <child>
     <key> one </key>
     <key> two </key>
     <key> Three </key>
</child>
</parent>

Список XMLModel должен быть таким:

NodeName: Parent, NodeId: 1, ParentId: 0

NodeName: Child, NodeId = 2, ParentId: 1

NodeName: Key, NodeId: 3, ParentId: 2

NodeName: Key, NodeId: 4, ParentId: 2

NodeName: Key, NodeId: 5, ParentId: 2

NodeName: Child, NodeId = 6, ParentId: 1

NodeName: Key, NodeId: 7, ParentId: 6

NodeName: Key, NodeId: 8, ParentId: 6

NodeName: Key, NodeId: 9, ParentId: 6


person Sujan    schedule 18.09.2018    source источник


Ответы (2)


Вы можете сделать это с помощью LINQ to XML

var xml = 
    XElement.Parse(@"<parent>
    <child>
        <key> one </key>
        <key> two </key>
        <key> Three </key>
    </child>
    <child>
        <key> one </key>
        <key> two </key>
        <key> Three </key>
    </child>
    </parent>");

var elementsAndIndex =
    xml
    .DescendantsAndSelf()
    .Select((node, index) => new { index = index + 1, node })
    .ToList();

List<XmlModel> elementsWithIndexAndParentIndex =
    elementsAndIndex
    .Select(
        elementAndIndex =>
            new
            {
                Element = elementAndIndex.node,
                Index = elementAndIndex.index,
                ParentElement = elementsAndIndex.SingleOrDefault(parent => parent.node == elementAndIndex.node.Parent)
            })
    .Select(
        elementAndIndexAndParent =>
            new XmlModel
            {
                NodeName = elementAndIndexAndParent.Element.Name.LocalName,
                NodeId = elementAndIndexAndParent.Index,
                ParentId = elementAndIndexAndParent.ParentElement == null ? 0 : elementAndIndexAndParent.ParentElement.index
            })
    .ToList();

Это должно дать вам следующие результаты:  введите описание изображения здесь

person James Cockayne    schedule 18.09.2018
comment
Спасибо! Это сработало. ты спас мне жизнь сегодня. Могу ли я узнать, есть ли какой-нибудь ресурс, через который я могу понять, как это работает? Я знаю, что вы использовали LINQ, но я хотел понять его, чтобы реализовать его в будущем. - person Sujan; 18.09.2018
comment
Привет, Суджан, документации на самом деле нет. Я полагаю, что большая часть кода проста, но в нем есть две особенности. 1) Использование перегрузки Select, которая дает вам индекс, а также элемент. 2). Зная, что вы можете сопоставить XElements по их ссылке, если они происходят из того же экземпляра XElement (я использовал это при поиске соответствующего родительского XElement). Думаю, я понял это из опыта и экспериментов! - person James Cockayne; 18.09.2018

Вы вручную десериализуете содержимое XML по итерациям. Используйте XmlSerializer. для автоматического сопоставления собственности.

Также, если вы хотите выполнить десериализацию вручную, используйте XDocument и XElement вместо класса XmlDocument. Это проще, быстрее и имеет современный API. XmlDocument относится к .NET 1.1 и устарел.

person Benni    schedule 18.09.2018