2013-10-12 67 views
0

在使用xmltextreader一段时间后,发现'use linq'几乎是每个.net xml相关问题的答案,我决定放弃它,到目前为止它已经非常好,但是我的文档工作有点奇怪,所以现在我遇到了一些问题。访问嵌套的子节点?

我正在使用的简化版本;

<a> 
    <b name="..." id="."> 
    <c id="..." type="..."> 
     <value_I_want>.....</value_I_want> 
    </c> 
    <c id="..." type="..."> 
     <value_I_want>.....</value_I_want> 
    </c> 

我需要查询“A”得到的属性和“C”的每个实例的元素 - 我无法查询“B”,因为它不是唯一的,将返回一堆不相干的东西。

我应该提到'a'元素不是文档的最终根。

任何想法?

回答

3

您可以选择一次性全部的'c'元素与LINQ查询:

XDocument doc = ...load your xml ... 
var c_elements = doc.Descendants("a") 
        .Descendants("b") 
        .Descendants("c); 

现在你从提取的属性或选择任何子节点想要的。

+0

'.Descendants'返回IEnumerable的'',所以'.OfType ()'是不必要的。 –

+0

@ZevSpitz谢谢。编辑。 – Alireza

+0

我不知道你可以链式的后代方法,完美的作品。谢谢。 – user1006221

2

使用LINQ ;-)

您要使用的后代方法,而不是元素的方法。例如:

 var xdoc = XDocument.Load("<yourxml/>"); 
     var celes = xdoc.Descendants("a").Descendants("c"); 

这将首先找到所有元素“a”,然后查找该集合以查找所有元素“c”。这可能是也可能不是你想要的。为了确保您有正确的亲子关系,你可以这样做:

 var xdoc = XDocument.Load("<yourxml/>"); 
     var celes = xdoc.Descendants("c") 
         .Where(x => (x.Parent != null) && (x.Parent.Name == "b")) 
         .Where(x => (x.Parent.Parent != null) && (x.Parent.Parent.Name == "a")); 
+0

['XElement'](http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.aspx)包含['Ancestors'](http://msdn.microsoft.com /en-us/library/bb348268.aspx)方法,它返回所有的祖先。要检查第一个和第二个父母,可以这样做:'.Where(x => {var l = x.Ancestors.Take(2).ToList(); return l.Count == 2 && l [0 ] .Name ==“b”&& l [1] .Name ==“a”;})' –