LINQ to XML. How to query List<T> with Linq recursively

吃可爱长大的小学妹 提交于 2020-01-06 06:59:22

问题


I'm generating XML file from structs. Some struct members are in List<T> type. I'm using linq queries but I'm stuck at some level.

My structs are like this:

public struct Project
{
    public string name;
    public List<Class> classes;
}

public struct Class
{
    public string name;
    public int class_id;
    public List<Var> vars;
}

public struct Var
{
    public string name;
    public string description;
    public int var_id;
    public List<Element> elements;
}

public struct Element
{
    public string name;
    public string description;
    public int element_id;
    public List<Element> elements;
    public List<Enm> enums;
}

public struct Enm
{
    public string name;
    public int value;
}

and I'm trying to create an XML file that looks like this

<PROJECT name="test project xml">
    <CLASS name="class1" class_id="1">
        <VAR name="var name 1" description="var description" var_id="1">
            <ELEMENT name="element name 1" description="element description" element_id="1"/>

            <ELEMENT name="element name 2" description="element description" element_id="2">
                <ELEMENT name="element name 3" description="element description" element_id="3"/>
            </ELEMENT>

            <ELEMENT name="element name 4" description="element description" element_id="4">
                <ELEMENT name="element name 5" description="element description" element_id="5">
                    <ELEMENT name="element name 6" description="element description" element_id="6"/>
                </ELEMENT>
            </ELEMENT>

            <ELEMENT name="element name 7" description="element description" element_id="7">
                <ENUM name="option 1" value="1"/>
                <ENUM name="option 2" value="2"/>
                <ENUM name="option 3" value="3"/>
            </ELEMENT>
        </VAR>

        <VAR name="var name 2" description="var description" var_id="2">
            <ELEMENT name="element name 8" description="element description" element_id="8">
        </VAR>
    </CLASS>
</PROJECT>

I wrote this code to generate the XML file, but it reaches only the first element level. Elements within elements are skipped. How can I get it to reach lower element levels? Also some element tags have enum tags.

XElement elm = new XElement("PROJECT", new XAttribute("name" project.name),
    project.classes.Select(x=> new XElement("CLASS", new XAttribute("name", x.name), new XAttribute("class_id", x.class_id),
        x.vars.Select(v=> new XElement("VAR", new XAttribute("name", v.name), new XAttribute("description", v.description), new XAttribute("var_id", v.var_id),
            v.elements.Select(e=> new XElement("ELEMENT", new XAttribute("name", e.name),new XAttribute("description", e.description),new XAttribute("element_id", e.element_id)
            )))))));

Is there an easy way to done this with minimum code lines? I think there must be a recursive method to fix my issue.


回答1:


Use Xml Serialization

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication132
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;

            XmlWriter writer = XmlWriter.Create(FILENAME, settings);
            XmlSerializer serializer = new XmlSerializer(typeof(Project));
            Project project = new Project();
            serializer.Serialize(writer, project);
        }
    }
    [XmlRoot("PROJECT")]
    public class Project
    {
        [XmlAttribute]
        public string name { get; set; }
        [XmlElement("CLASS")]
        public List<cClass> classes { get; set; }

        public Project()
        {
            name = "test project xml";
            classes = new List<cClass>() {
                new cClass() {
                    name = "class1",
                    class_id = 1,
                    vars = new List<Var>() {
                        new Var() { 
                            name = "var name 1",
                            description = "var description",
                            var_id = 1,
                            elements = new List<Element>() {
                                new Element() {
                                   name = "element name 1",
                                   description = "element description",
                                   element_id = 1
                                },
                                new Element() {
                                   name = "element name 2",
                                   description = "element description",
                                   element_id = 2,
                                   elements = new List<Element>() {
                                       new Element() {
                                           name = "element name 3",
                                           description = "element description",
                                           element_id = 3
                                       }
                                   }
                                },
                                new Element() {
                                   name = "element name 4",
                                   description = "element description",
                                   element_id = 4,
                                   elements = new List<Element>() {
                                        new Element() {
                                           name = "element name 5",
                                           description = "element description",
                                           element_id = 5,
                                           elements = new List<Element>() {
                                               new Element() {
                                                   name = "element name 6",
                                                   description = "element description",
                                                   element_id = 6
                                               }
                                           }
                                        }
                                   }
                                },
                                new Element() {
                                   name = "element name 7",
                                   description = "element description",
                                   element_id = 7,
                                   enums = new List<Enm>() {
                                       new Enm() {
                                          name = "option 1",
                                          value = 1
                                       },
                                       new Enm() {
                                          name = "option 2",
                                          value = 2
                                       },
                                       new Enm() {
                                          name = "option 3",
                                          value = 3
                                       }
                                   }
                                }
                            }
                        },
                        new Var() { 
                            name = "var name 2",
                            description = "var description",
                            var_id = 2,
                            elements = new List<Element>() {
                                new Element() {
                                   name = "element name 8",
                                   description = "element description",
                                   element_id = 8
                                }
                            }
                        }
                   }
                }
            };

        }
    }

    public class cClass
    {
        [XmlAttribute]
        public string name { get; set; }
        [XmlAttribute]
        public int class_id;
        [XmlElement("VAR")]
        public List<Var> vars;
    }

    public class Var
    {
        [XmlAttribute]
        public string name;
        [XmlAttribute]
        public string description;
        [XmlAttribute]
        public int var_id;
        [XmlElement("ELEMENT")]
        public List<Element> elements;
    }

    public struct Element
    {
        [XmlAttribute]
        public string name;
        [XmlAttribute]
        public string description;
        [XmlAttribute]
        public int element_id;
        [XmlElement("ELEMENT")]
        public List<Element> elements;
        [XmlElement("EMNU")]
        public List<Enm> enums;
    }

    public struct Enm
    {
        [XmlAttribute]
        public string name;
        [XmlAttribute]
        public int value;
    }

}


来源:https://stackoverflow.com/questions/58181213/linq-to-xml-how-to-query-listt-with-linq-recursively

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!