1

我在遍历 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 Level2
      • ChildCat Level3_1
      • ChildCat Level3_2

但结果如下所示:

  • 猫 1 级
    • ChildCat Level2
      • ChildCat Level3_1
      • ChildCat Level3_2
    • ChildCat Level3_1
    • ChildCat Level3_2
    • ChildCat Level3_1
    • ChildCat Level3_2
  • ChildCat Level2
    • ChildCat Level3_1
    • ChildCat Level3_2
  • ChildCat Level3_1
  • ChildCat Level3_2

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

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

更新:

感谢“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);
    }
}
4

1 回答 1

1

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

Elements文档在这里

于 2012-10-25T21:57:59.140 回答