C# 从XML文件创建嵌套节点的属性列表

C# 从XML文件创建嵌套节点的属性列表,c#,.net,xml,winforms,C#,.net,Xml,Winforms,我有一个XML文件,如下所示: <?xml version="1.0" encoding="utf-8"?> <files> <file name="1"> <file name="4"> </file> </file> <file name="2"> </file> <file name="3">

我有一个XML文件,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<files>
    <file name="1">
        <file name="4">     
        </file> 
    </file>
    <file name="2">
    </file>
    <file name="3">
        <file name="5">
            <file name="7">
            </file>
        </file>
    </file>
</files>
因为我可以知道所需的节点处于哪个级别

你能告诉我你有这样一份清单的想法吗

更新:在的回答之后,如果子节点位于同一层次结构中,则将按以下方式进行更新

XML文件:

<files>
<file name="1">
    <file name="4"/>     
    <file name="2">
      <file name="3"/>
    </file> 
</file>
<file name="5"/>

注:在测试了一些示例后,我注意到,如果有两个或更多来自同一级别的孩子,我必须先有父母,然后才有孩子。

似乎您可能想要:

  • 对于所有没有子元素的
    文件
    元素
  • 编制
    文件
    元素祖先
  • 为每个祖先获取
    name
    属性,并将其连接在一起
所以我认为这应该是可行的,创建一个
IEnumerable

完整示例:

using System;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        var hierarchy = doc.Descendants("file")
                   .Where(x => x.Element("file") == null)
                   .Select(x => x.AncestorsAndSelf("file")
                                 .Reverse()
                                 .Select(f => (int) f.Attribute("name"))
                                 .ToList());

        foreach (var item in hierarchy)
        {
            Console.WriteLine(string.Join(", ", item));
        }
    }
}
输出:

1, 4
2
3, 5, 7
另一种方法是获取所有顶级
文件
元素,并为每个元素查找所有子体:

using System;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        var hierarchy = doc.Root.Elements("file")
                   .Select(x => x.DescendantsAndSelf("file")
                                 .Select(f => (int) f.Attribute("name"))
                                 .ToList());

        foreach (var item in hierarchy)
        {
            Console.WriteLine(string.Join(", ", item));
        }
    }
}
现在这两种方法给出了相同的结果,因为基本上每个顶级
文件
元素都有一条“线”。但是,如果你有这样的XML:

,你应该考虑你想要的结果是什么。
<files>
    <file name="1">
        <file name="4"/>     
        <file name="2">
          <file name="3"/>
        </file> 
    </file>
    <file name="5"/>
</files>


在这里,名为1的顶级元素有两个子元素-您希望结果是什么?

您可以使用。例如:

var document = XDocument.Load(@"d:\xml.xml");
var list = document.Root.Elements()
                   .Select(x=>string.Join(",", 
                       x.DescendantsAndSelf().Select(d=>d.Attribute("name").Value)))
                   .ToList();
上面示例的结果是类型
List
,其中每个元素在层次结构中都包含逗号分隔的名称。如果您需要每个元素包含层次结构的
IEnumerable
,以获得更大的灵活性,请从select语句中删除
string.Join

编辑

答案是根据您的原始帖子发布的,每个文件只有一个子文件。如果您有多个文件作为一个文件的子文件,则应按照Jon的说明使用解决此问题。

谢谢您的回答。XML文件是什么意思?@SaberJalilzadeh:哎呀,对不起,我没有缩进那个答案。再看一眼:)好吧,问得很好。对于这种类型的XML文件,结果将是1,4-1,2,3-5。使用
anstorsandself
解决问题的方法非常好!最适合您提供的sapmle xml。非常适合xml文件和您描述的案例!!非常感谢。:)答案是根据您的原始帖子发布的,每个文件只有一个子文件。如果您有多个文件作为一个文件的子文件,则应使用Jon的中所述的方法解决此问题。
using System;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        var hierarchy = doc.Root.Elements("file")
                   .Select(x => x.DescendantsAndSelf("file")
                                 .Select(f => (int) f.Attribute("name"))
                                 .ToList());

        foreach (var item in hierarchy)
        {
            Console.WriteLine(string.Join(", ", item));
        }
    }
}
<files>
    <file name="1">
        <file name="4"/>     
        <file name="2">
          <file name="3"/>
        </file> 
    </file>
    <file name="5"/>
</files>
var document = XDocument.Load(@"d:\xml.xml");
var list = document.Root.Elements()
                   .Select(x=>string.Join(",", 
                       x.DescendantsAndSelf().Select(d=>d.Attribute("name").Value)))
                   .ToList();