问题
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