2012-07-04 1 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> 

에서 C 번호와 다르게 분기 부모 노드에서 잎을 가져, I 는의에 속하는 프로그램에만 잎을 검색하고 싶습니다 "P"parents 예를 들어 위의 예에서 P2 "AA"를 선택하면 l_A가 l_F로되고 P3 "BBB"가 l_D가 l_F가됩니다.깊은 10 레벨까지 다양하게 중첩 된 수천 개의 노드를 포함하는 XML 문서에서 XML 문서

+0

고유합니다. Xpath에서 각 노드의 속성을 확인하는 것은 1000 개 이상의 노드가 관련되어있을 때 번거로운 작업입니다. 더 효율적인 방법이 있는지 궁금해서 ... – jacques

답변

1

뭔가 (문자열의 목록을 반환) XmlDocument에 의해

당신의 의 XPath 수 있습니다 리터 (당신은 LINQ를 사용하지 않는 경우) 이케이 :

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

과 같은 코드 :

초기 아이디어는 XPath를 사용하고 거기에 부모의 존재를 확인하지만 불행히도 부모 식별자는 텍스트 속성은, 고유하지 않은 것이었다
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; 
} 
+0

완벽하게 작동합니다! 큰! 많은 thnaks – jacques

0

하나의 방법이 XPath를을 사용하고 ... Text 속성이 항상 존재하는 경우는 속성이 널 (null) 검사를 제거 할 수 있습니다

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); 

이 같은