You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读取嵌套XML文件并将数据存储到列表中?

嵌套XML数据提取最优实现方案

问题描述

我有一个以int和string类型数据为主的嵌套XML文件,需要将其中的数据提取并存储到列表中供后续使用。此前尝试使用using System.Xml;创建阅读器,通过reader.ReadToFollowing("Something")结合reader.GetAttribute("Id")的方式读取,但无法获取到深层数据;而该方法在简单结构XML(如示例中的Animal结构)中可正常工作,现寻求最优实现方案。

目标XML结构

<AllThings>
      <Anythings>
        <Anything Step="1" Name="1">
          <Somethings>
            <Something Id="10">
              <Things>
                <Thing Id="11">abc</Thing>
                <Thing Id="12">123</Thing>
              </Things>
            </Something>
            <Something Id="20">
              <Things>
                <Thing Id="21">cde</Thing>
                <Thing Id="22">345</Thing>
              </Things>
            </Something>
            <Something Id="30">
              <Things>
                <Thing Id="31">efg</Thing>
                <Thing Id="32">567</Thing>              
              </Things>
            </Something>
            <Something Id="40">
              <Things>
                <Thing Id="41">ghi</Thing>
                <Thing Id="42">789</Thing>                
              </Things>
            </Something>
    </Somethings>
    </Anything>
    <Anything Step="2" Name="2">
          <Somethings>
            <Something Id="10">
              <Things>
                <Thing Id="11">aaa</Thing>
                <Thing Id="12">111</Thing>
              </Things>
            </Something>
            <Something Id="20">
              <Things>
                <Thing Id="21">ccc</Thing>
                <Thing Id="22">333</Thing>
              </Things>
            </Something>
            <Something Id="30">
              <Things>
                <Thing Id="31">eee</Thing>
                <Thing Id="32">555</Thing>              
              </Things>
            </Something>
            <Something Id="40">
              <Things>
                <Thing Id="41">ggg</Thing>
                <Thing Id="42">777</Thing>                
              </Things>
            </Something>
        </Somethings>
        </Anything>
    </Anythings>
</AllThings>

可正常处理的简单XML示例

<Animal type="cat">
  <Name>Bob</Name>
  <Age>8</Age>
</Animal>

解决方案

1. 改进XmlReader方式(适合大文件,内存友好)

XmlReader是流式读取,需要手动处理节点嵌套层级。先定义对应数据类,再通过循环遍历节点逐层解析:

// 定义数据类
public class ThingData
{
    public int Step { get; set; }
    public string Name { get; set; }
    public int SomethingId { get; set; }
    public int ThingId { get; set; }
    public string Value { get; set; }
}

// 读取逻辑
List<ThingData> thingList = new List<ThingData>();
using (XmlReader reader = XmlReader.Create("your-xml-file-path.xml"))
{
    int currentStep = 0;
    string currentName = string.Empty;
    int currentSomethingId = 0;

    while (reader.Read())
    {
        // 记录当前Anything的Step和Name
        if (reader.NodeType == XmlNodeType.Element && reader.Name == "Anything")
        {
            currentStep = int.Parse(reader.GetAttribute("Step"));
            currentName = reader.GetAttribute("Name");
        }
        // 记录当前Something的Id
        else if (reader.NodeType == XmlNodeType.Element && reader.Name == "Something")
        {
            currentSomethingId = int.Parse(reader.GetAttribute("Id"));
        }
        // 提取Thing节点数据并加入列表
        else if (reader.NodeType == XmlNodeType.Element && reader.Name == "Thing")
        {
            ThingData data = new ThingData
            {
                Step = currentStep,
                Name = currentName,
                SomethingId = currentSomethingId,
                ThingId = int.Parse(reader.GetAttribute("Id")),
                Value = reader.ReadElementContentAsString()
            };
            thingList.Add(data);
        }
    }
}

2. LINQ to XML(XDocument)方式(代码简洁,适合中小文件)

通过LINQ查询直接遍历嵌套节点,代码可读性高:

List<ThingData> thingList = new List<ThingData>();
XDocument doc = XDocument.Load("your-xml-file-path.xml");

var query = from anything in doc.Descendants("Anything")
            let step = int.Parse(anything.Attribute("Step").Value)
            let name = anything.Attribute("Name").Value
            from something in anything.Descendants("Something")
            let somethingId = int.Parse(something.Attribute("Id").Value)
            from thing in something.Descendants("Thing")
            select new ThingData
            {
                Step = step,
                Name = name,
                SomethingId = somethingId,
                ThingId = int.Parse(thing.Attribute("Id").Value),
                Value = thing.Value
            };

thingList = query.ToList();

3. XmlDocument+XPath方式(传统DOM方式)

用XPath定位节点,再向上遍历父节点获取层级数据:

List<ThingData> thingList = new List<ThingData>();
XmlDocument doc = new XmlDocument();
doc.Load("your-xml-file-path.xml");

XmlNodeList thingNodes = doc.SelectNodes("//Thing");
foreach (XmlNode thingNode in thingNodes)
{
    // 向上获取父级节点数据
    XmlNode somethingNode = thingNode.ParentNode.ParentNode;
    XmlNode anythingNode = somethingNode.ParentNode.ParentNode;

    ThingData data = new ThingData
    {
        Step = int.Parse(anythingNode.Attributes["Step"].Value),
        Name = anythingNode.Attributes["Name"].Value,
        SomethingId = int.Parse(somethingNode.Attributes["Id"].Value),
        ThingId = int.Parse(thingNode.Attributes["Id"].Value),
        Value = thingNode.InnerText
    };
    thingList.Add(data);
}

方案选择建议

  • 若XML文件体积较大(几百MB以上),优先选XmlReader,流式读取不占用大量内存;
  • 若文件体积小,追求代码简洁易维护,选LINQ to XML;
  • 若熟悉XPath语法,XmlDocument+XPath也是可行选项。

内容的提问来源于stack exchange,提问作者barth87

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:01:15