2012-02-19 14 views
3

下の例では、すべてのサブページを取得しようとしています。 XMLは、私は次のように作成しようとしました私のXML内のすべてのサブノードを見つけるには

<?xml version="1.0"?> 

<main> 
    <group title="Server Tools" enabled="True"> 
    <page title="Server Tools" pageId="1" subtitle="Tools for servers" enabled="True"> 
     <subpage title="Name-1" pageId="2" subtitle="" enabled="True">   
     <subpage title="Name-2" pageId="3" subtitle="" enabled="True"> 
      <subpage title="Name-3" pageId="4" subtitle="" enabled="True"> 
       <subpage title="Name-4" pageId="5" subtitle="" enabled="True">     
       </subpage> 
      </subpage> 
     </subpage> 
     </subpage> 
    </page> 
    </group> 
</main> 

この(シンプルなレイアウト)のように見えますが、それは最初の「サブページ」を検索します。

XmlDocument doc = new XmlDocument(); 
doc.Load(path + @"\config.xml"); 

XmlNodeList groups = doc.SelectNodes("main/group"); 
foreach (XmlNode group in groups) 
{ 
    String groupTitle = group.Attributes["title"].InnerText; 
    String groupEnabled = group.Attributes["enabled"].InnerText; 
    maxResults = Convert.ToInt32(group.Attributes["maxResults"].InnerText); 

    if (groupEnabled == "True") 
    { 
     firstGroup.Title = groupTitle; 
     XmlNodeList pages = group.SelectNodes("page"); 

     foreach (XmlNode page in pages) 
     { 
      String pageTitle = page.Attributes["title"].InnerText; 
      int pageId = Convert.ToInt32(page.Attributes["pageId"].InnerText); 
      String subtitle = page.Attributes["subtitle"].InnerText; 
      String pageEnabled = page.Attributes["enabled"].InnerText; 

      if(pageEnabled == "True") 
      { 
      firstGroup.Items.Add(new PageItem(pageId, pageTitle, subtitle)); 
      pageList.Add(pageId); 
      XmlNodeList subpages = page.SelectNodes("subpage"); 

      foreach (XmlNode subpage in subpages) 
      { 
       string subpageTitle = subpage.Attributes["title"].InnerText; 
       int subpageId = Convert.ToInt32(subpage.Attributes["pageId"].InnerText); 
       String subpageSubtitle = subpage.Attributes["subtitle"].InnerText; 
       String subpageEnabled = subpage.Attributes["enabled"].InnerText; 

       if (subpageEnabled == "True") 
       { 
        subpageDic.Add(subpageId, new Tuple<int, string, string>(pageId, subpageTitle, subpageSubtitle)); 
       } 
      } 
      } 
     } 
    } 
} 

私は間違っていますか?私はちょうどサブページの下のすべてのサブページを通過し、利用可能な属性を取得したい。

ありがとうございます。

+2

おそらく、サブページがネストされている可能性があります。 – Krizz

+0

ネストされたサブページをループするには、再帰呼び出しを使用してください。 – pistipanko

+0

こんにちはKrizz、そうですね、このレイアウトをやる方が簡単です。私は複数のページノードとサブページを持つことができますが、必要に応じてサブページもサブ、サブ、サブページを持つ必要があります。任意のアイデア;) – cptrico

答えて

1

あなたの問題はここにです:

XmlNodeList subpages = page.SelectNodes("subpage"); 

subpagespageに含まれる要素の子だけsubpageの要素が含まれています。

ただし、すべての子孫pageが必要です。

解決

このと上の行を交換:

XmlNodeList subpages = page.SelectNodes(".//subpage"); 

を可変subpagesは、現在のノードpageの全てsubpage子孫を含んでいます。

+0

非常にきれいな答えをありがとう、これはあなたの問題です、これはあなたがそれを修正する方法です、私はこれが好きです。ありがとうございました。それは今私が望むように働いています。 – cptrico

+0

@cptrico:どうぞよろしくお願いいたします。 –

0

XMLDocumentを忘れて、代わりにLINQ to XMLを使用してください。 XDocument.Load()を使用してドキュメントを読み込んだ後は、

IEnumerable<XElement> de= 
    from el in xmlTree.Descendants("subpage") 
    select el; 
    foreach (XElement el in de) 
Console.WriteLine(el.Attributes("title"), el.Attributes("pageID"));//etc 
+0

これは、トップレベルの 'subpage'要素、例を使って)、** all **ではありません(例では10)。 – Yuck

+1

いいえ、私はそれがトップレベルのものを含むすべてのサブページの要素を返すと思います。関連するページ要素についての情報は得られませんが、質問のコードスニペットを見ると、必要があるかどうかはわかりません。 –

+0

いいえ、*すべての*サブページ要素を返します。 http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.descendants.aspxを参照してください。そして、私がここに投稿した他のコードよりもずっと簡単です。 – deadlyvices

0

などのコードを使用できます。

 string path = @"..\LinqToXml\LinqToXml\config.Xml"; 

     XElement doc2 = XElement.Load(path); 

     var element = from t in doc2.Elements("group").Elements("page").Descendants() select t; 

     foreach (var el in element) 
     { 
      if (el.HasAttributes) 
      { 
       foreach (var att in el.Attributes()) 
       { 
        Debug.WriteLine(att.Value); 
       } 
      } 
     } 
+1

'subpage'要素だけでなく、これで* everything *を選択しています。 – Yuck

+0

すべてのあなたのクイック返信をありがとう。入れ子にするのが難しい場合は、xmlを別のものに変更する方が良いと思いますか?または?複数のサブレベルをサポートできるだけで十分です。 (うん)あなたは私がそれをすべて解析するために何をすべきか考えていますか? :) – cptrico

+0

フォーマットに固執し、LINQ to XMLを使用して私の答えを見てください。それは動作し、私を信頼します。 – deadlyvices

2

たぶんXPATHで試してみてください。

XmlDocument document = ...; 
var nodes = document.SelectNodes("//subpage"); 

nodesは、このコレクションが含まれます:

<subpage title="Name-1" pageId="2" subtitle="" enabled="True">   
    <subpage title="Name-2" pageId="3" subtitle="" enabled="True"> 
     <subpage title="Name-3" pageId="4" subtitle="" enabled="True"> 
       <subpage title="Name-4" pageId="5" subtitle="" enabled="True">     
       </subpage> 
      </subpage> 
     </subpage> 
    </subpage> 
<subpage title="Name-2" pageId="3" subtitle="" enabled="True"> 
    <subpage title="Name-3" pageId="4" subtitle="" enabled="True"> 
    <subpage title="Name-4" pageId="5" subtitle="" enabled="True">     
</subpage> 

さて、ノード内の各ノードに対して再帰的に//subpage選択します。

編集:

XPATHは強力なツールです。このxpathで試してください://../subpage。結果は次のとおりです。一度XElementオブジェクトに変換

<subpage title="Name-1" pageId="2" subtitle="" enabled="True">   
     <subpage title="Name-2" pageId="3" subtitle="" enabled="True"> 
      <subpage title="Name-3" pageId="4" subtitle="" enabled="True"> 
       <subpage title="Name-4" pageId="5" subtitle="" enabled="True">     
       </subpage> 
      </subpage> 
     </subpage> 
    </subpage> 
----------------------- 
<subpage title="Name-2" pageId="3" subtitle="" enabled="True"> 
    <subpage title="Name-3" pageId="4" subtitle="" enabled="True"> 
     <subpage title="Name-4" pageId="5" subtitle="" enabled="True">     
     </subpage> 
    </subpage> 
</subpage> 
----------------------- 
<subpage title="Name-3" pageId="4" subtitle="" enabled="True"> 
    <subpage title="Name-4" pageId="5" subtitle="" enabled="True">     
    </subpage> 
</subpage> 
----------------------- 
<subpage title="Name-4" pageId="5" subtitle="" enabled="True"> 
</subpage> 
+0

あなたの例をありがとう:)非常に完全に助けてください。 – cptrico

0

は、あなたが特定の名前を持つすべての要素を選択するには「//」とともにXPathSelectElements extension方法を利用することができます。

using System.Xml.XPath; 

... 

var path = "<Your path>"; 
var doc = XElement.Load(path); 

var subPages = doc.XPathSelectElements("//subpage[@pageId != '']") 
        .Select(x => new 
           { 
            Id = Convert.ToInt32(x.Attribute("pageId").Value, 
            SubTitle = x.Attribute("subtitle").Value, 
            Enabled = Convert.ToBoolean(x.Attribute("enabled").Value) 
           } 
       ) 
        .ToDictionary(u => u.Id, u => new Tuple<int, string, string>(u.Id, u.SubTitle, u.Enabled) 
+0

注:「字幕」属性と「有効」属性がXMLにも存在し、「pageId」属性値と「有効」属性値が予想される型を解析することを安全に確認していないという前提では、少し安全ではありませんでした。あなたにその部分を残すでしょう... – Reddog

関連する問題