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レベル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

デバッグの結果、これは再帰コードが子孫「Category」を検索しているためであることがわかりましたが、サブカテゴリノードの名前も「Category」です。したがって、要素「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 に答える