C# 解析 XML 并将其存储到 Class

C# Parsing an XML and storing it into a Class

我需要解析一个 XML 并将其存储到一个 class 中,但它让我头疼的事情比我愿意承认的要多得多。

假设 XML 看起来像这样:

<PARENT>
    <ITEM>
        <DATA1>
            <A>12345</A>
            <B>12345</B>
            <C>12345</C>
        </DATA1>
        <DATA2>
            <D>12345</D>
            <E>12345</E>
            <F>12345</F>
        </DATA2>
        <DATA3>
            <ITEM>
                <G/>
                <H>111</H>
                <I>223</I>
            </ITEM>
            <ITEM>
                <G/>
                <H>2342</H>
                <I>25323</I>
            </ITEM>
            <ITEM>
                <G>185</G>
                <H>63611</H>
                <I/>
            </ITEM>
        </DATA3>
    </ITEM>
    <ITEM>
        <DATA1>
            <A>23456</A>
            <B>23456</B>
            <C>23456</C>
        </DATA1>
    </ITEM>
</PARENT>

我面临的第一个问题是名称“ITEM”不仅作为“PARENT[=42”的子节点出现=]”,但也在“DATA3”下再次使用,所以如果我像这样搜索

XDocument doc = XDocument.Parse(tmp);
IEnumerable<XElement> tmp_list = doc.Descendants(XName.Get("ITEM"));

它会给我五个结果,而不是两个。

我也已经尝试过这样搜索路径 //PARENT/ITEM 的方法:

string file = @"C:\temp\test.xml";

var document = XDocument.Load(file);
var namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("empty", "random:namespace:name");

IEnumerable<XElement> ele_list = document.XPathSelectElements("//PARENT//ITEM", namespaceManager);

但它也不起作用,因为它还会获取所有孙节点...

问题 1)如何正确地将搜索限制在顶级节点?

问题 2) 我将如何以最有效的方式继续并将整个事情存储到 class 中?我试过将完整的 XML 响应复制粘贴到像 http://xmltocsharp.azurewebsites.net/ 这样的网站,但他们似乎都在为重复的名称“ITEM”而苦苦挣扎,基本上创建一个class 合并了所有不同的“ITEM”子节点。是否有可能以简单有效的方式填写项目列表?我希望基本上有一些类似的东西:

List<DataItem> grd_list = doc.Descendants(XName.Get("ITEM"))
   .Select(f => new DataItem()
   {
      DATA1 = f.Element(XName.Get("DATA1")).Document.ToString(),
      DATA2 = f.Element(XName.Get("DATA2")).Document.ToString(),
      //etc.....
   }).ToList();

但我知道上面的 LINQ 必须比这更复杂,因为 DATA1 等也需要有子节点。

您可以使用序列化程序 XML(这只是您 xml 之后的一个示例)

您可以通过在 class ITEM 的定义中定义所有情况来避免 item 的问题。因此项目不存在(G、H、I 或 DATA1、DATA2.. 将为空)。

using System.Xml.Serialization;
XmlSerializer serializer = new XmlSerializer(typeof(PARENT));
using (StringReader reader = new StringReader(xml))
{
   var test = (PARENT)serializer.Deserialize(reader);
}
  :
  :
[XmlRoot(ElementName = "DATA1")]
public class DATA1
{

    [XmlElement(ElementName = "A")]
    public string A { get; set; }

    [XmlElement(ElementName = "B")]
    public string B { get; set; }

    [XmlElement(ElementName = "C")]
    public string C { get; set; }
}

[XmlRoot(ElementName = "DATA2")]
public class DATA2
{

    [XmlElement(ElementName = "D")]
    public string D { get; set; }

    [XmlElement(ElementName = "E")]
    public string E { get; set; }

    [XmlElement(ElementName = "F")]
    public string F { get; set; }
}

[XmlRoot(ElementName = "ITEM")]
public class ITEM
{

    [XmlElement(ElementName = "G")]
    public string G { get; set; }

    [XmlElement(ElementName = "H")]
    public string H { get; set; }

    [XmlElement(ElementName = "I")]
    public string I { get; set; }

    [XmlElement(ElementName = "DATA1")]
    public DATA1 DATA1 { get; set; }

    [XmlElement(ElementName = "DATA2")]
    public DATA2 DATA2 { get; set; }

    [XmlElement(ElementName = "DATA3")]
    public DATA3 DATA3 { get; set; }
}

[XmlRoot(ElementName = "DATA3")]
public class DATA3
{
    [XmlElement(ElementName = "ITEM")]
    public List<ITEM> ITEM { get; set; }
}

[XmlRoot(ElementName = "PARENT")]
public class PARENT
{
    [XmlElement(ElementName = "ITEM")]
    public List<ITEM> ITEM { get; set; }
}