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

时间:2016-03-22 08:20:00

标签: 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">
        <file name="5">
            <file name="7">
            </file>
        </file>
    </file>
</files>

现在我想创建一个字符串/数字列表,它将所有属性name保存在列表/数组中,其中包含嵌套节点层次结构。例如,对于上面的XML文件,预期的列表是

(1,4
2
3,5,7)

因为我可以知道所需级别的节点。

请您告诉我您对列表有什么想法?

更新:Jon回答后,如果子节点位于同一层次结构中,则会采用以下方式。

XML文件:

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

和所需的输出:

1,4
1,2
1,2,3
5

PS。在测试了一些例子之后,我注意到我必须有第一个父母,然后是孩子,以防有两个或更多同一级别的孩子。

2 个答案:

答案 0 :(得分:3)

似乎你可能想要:

  • 对于没有孩子 namespace ASPMVC.Hubs { public class CommunicationsHub : Hub { public void Send(string name, string message) { Debug.WriteLine("---------->"+name); //Call the addNewMessageToPage method to update clients. Clients.All.addNewMessageToPage(name, message); } } } 元素的所有file元素
  • 制定file元素祖先
  • 获取每个祖先的file属性,并将其加入

所以我认为这应该有用,创建一个name

IEnumerable<List<int>>

完整示例:

var hierarchy = doc.Descendants("file")
                   .Where(x => x.Element("file") == null)
                   .Select(x => x.AncestorsAndSelf("file")
                                 .Reverse()
                                 .Select(f => (int) f.Attribute("name"))
                                 .ToList());

输出:

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 元素,并为每个元素找到所有后代:

file

现在这两个人都给出了相同的结果,因为你基本上得到了一条&#34;线&#34;来自每个顶级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,你应该考虑你想要的结果:

file

这里名为1的顶级元素有两个孩子 - 你想要的结果是什么?

答案 1 :(得分:1)

您可以使用XElement.DescendantsAndSelf展平层次结构。例如:

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<string>类型,其中每个元素在层次结构中包含逗号分隔的名称。如果您需要每个元素包含IEnumerable<string>层次结构以获得更大的灵活性,请从select语句中删除string.Join

修改
答案是根据您的原始帖子发布的,每个文件只有一个文件作为孩子。如果您有多个文件作为文件的子文件,则应使用AncestorsAndSelf中所述的answer来解决问题。