2012-07-04 21 views
3
<Root> 
    <P1 Text ="A" > 
    <P2 Text = "AA"> 
     <P3 Text = "AAA"> 
     <L Text = "l_A"/> 
     <L Text = "l_B"/> 
     <L Text = "l_C"/> 
     </P3> 
     <P3 Text = "BBB"> 
     <L Text = "l_D"/> 
     <L Text = "l_E"/> 
     <L Text = "l_F"/> 
     </P3> 
    </P2> 
    <P2 Text = "BB"> 
     <L Text = "l_G"/> 
     <L Text = "l_H"/> 
     <L Text = "l_I"/> 
    </P2> 
    </P1> 
</Root> 

從包含數千個可變嵌套節點的可達10級深的XML文檔,我 想檢索程序只屬於任何的葉子「P」父母 如下:例如,在上面的例子中,選擇P2「AA」將產生1_A到1_F,並且P3「BBB」將給出1_F到1_F。檢索從C#不同分支的父節點葉的XML文檔

+0

最初的想法是使用XPath和以檢查它的父存在,但不幸的是,父母標識符不是唯一的,只有文本屬性是獨特的。涉及1000多個節點時,檢查Xpath中每個節點的屬性是很麻煩的。我想知道是否有更有效的方法... – jacques

回答

1

像這樣的東西(返回一個字符串列表):

XDocument doc = XDocument.Load(@"test.xml"); 

    string level = "P3"; 
    string levelAttr = "AAA"; 

    var list = (from d in doc.Descendants(level) 
       let xAttribute = d.Attribute("Text") 
       where xAttribute != null && xAttribute.Value == levelAttr 
       from l in d.Descendants("L") 
       let lAttribute = l.Attribute("Text") 
       where lAttribute != null 
       select lAttribute.Value); 

您可以刪除該屬性null檢查,如果Text屬性是永遠存在......

+0

完美的作品!大!許多thnaks – jacques

0

一個方法是使用XPath的通過XmlDocument(如果你不使用LINQ

的XPath可爲L IKE在此:

//P2[@Text='AA']//L/@Text 

和你這樣的代碼:

XmlDocument document; //init and load it 

static List<String> GetLeavesText(int pLevel /* 2 */, string pText /* AA */) 
{ 
    var result = new List<String>(); 

    //loaded document 

    var nodeList = document.SelectNodes(String.Format(@"//P{0}[@Text='{1}']//L/@Text", pLevel, pText)); 
    if (nodeList != null) 
     foreach (XmlNode xmlNode in nodeList) 
     { 
      result.Add(xmlNode.InnerText); 
     } 

    return result; 
}