我在遍历 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
- ChildCat Level2
但结果如下所示:
- 猫 1 级
- ChildCat Level2
- ChildCat Level3_1
- ChildCat Level3_2
- ChildCat Level3_1
- ChildCat Level3_2
- ChildCat Level3_1
- ChildCat Level3_2
- ChildCat Level2
- 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);
}
}