【问题标题】:Loop through XML with same node-values循环通过具有相同节点值的 XML
【发布时间】:2012-10-16 02:49:06
【问题描述】:

我在遍历 XML 文件并将其表示为例如 TreeView 时遇到了困难。我的 XML 的结构如下所示:

<Categories>
  <Category Name="Cat Level1">
    <Categories>
      <Category Name="ChildCat Level 2">
        <Categories>
          <Category Name="ChildCat Level3_1" />
          <Category Name="ChildCat Level3_2" />
        </Categories>
      </Category>
    </Categories>
  </Category>
</Categories>

我写了一个递归函数来循环这个 XML,这里是:

private void CreateTreeStructure(XDocument xDoc)
{
    foreach(var element in xDoc.Descendants("Category"))
    {
        var node = new TreeNode(element.Attribute("Name").Value);
        treeView1.Nodes.Add(node);
        ReadChildren(element.Descendants("Categories"), node);
    }
}

private void ReadChildren(IEnumerable<XElement> element, TreeNode node)
{
    foreach (var child in element.Descendants("Category"))
    {
        var childNode = new TreeNode(child.Attribute("Name").Value);
        node.Nodes.Add(childNode);
        ReadChildren(child.Descendants("Categories"), childNode);
    }
}

结果是预期的和非预期的。我希望这个 XML 在 TreeView 中,所以结果应该类似于:

  • 猫 1 级
    • ChildCat 2 级
      • ChildCat Level3_1
      • ChildCat Level3_2

但是结果是这样的:

  • 猫 1 级
    • ChildCat 2 级
      • ChildCat Level3_1
      • ChildCat Level3_2
    • ChildCat Level3_1
    • ChildCat Level3_2
    • ChildCat Level3_1
    • ChildCat Level3_2
  • ChildCat 2 级
    • ChildCat Level3_1
    • ChildCat Level3_2
  • ChildCat Level3_1
  • ChildCat Level3_2

经过一些调试我发现这是因为我的递归代码正在寻找后代“类别”,但子类别节点也被命名为“类别”。因此,应该只找到元素“Cat Level 1”的第一个函数也循环遍历名为 Category 的其他节点。现在我有点坚持这一点,我无法改变 XML 的结构。

那么,有没有人知道如何循环这个 XML 而无需每次都读取 all 子节点?提前致谢!

更新:

感谢“davisoa”的回答,我设法解决了这个问题。下面是我使用的代码,如果有人有同样的问题,这里是答案:

private void CreateTreeStructure(XDocument xDoc)
{
    foreach (var element in xDoc.Root.Elements("Category"))
    {
        var node = new TreeNode(element.Attribute("Name").Value);
        treeView1.Nodes.Add(node);
        if (element.HasElements) 
            ReadChildren(element.Element("Categories"), node);
    }
}

private void ReadChildren(XElement element, TreeNode node)
{
    foreach (var child in element.Elements("Category"))
    {
        var childNode = new TreeNode(child.Attribute("Name").Value);
        node.Nodes.Add(childNode);
        if(child.HasElements)
            ReadChildren(child.Element("Categories"), childNode);
    }
}

【问题讨论】:

  • 你试过用Elements代替Descendants吗?听起来它只返回直接的孩子。 msdn.microsoft.com/en-us/library/bb348975.aspx
  • 那我应该在哪里使用 Elements 而不是 Descendants?无处不在或在 foreach 部分或...?
  • 找到了! :) 将您的评论放在答案中,我会将其标记为正确答案! ;)

标签: c# xml loops recursion linq-to-xml


【解决方案1】:

如果您使用Elements 方法而不是Descendants,它只会返回直接子代。这应该可以解决问题。

Elements 文档是 here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多