2012-01-26 151 views
2

我试图查询包含WCF条目的web.Config文件。linq to xml获取所有子节点

<service>节点有一个name attribute,我试图匹配。到目前为止,我的代码在进行匹配时工作正常,但我的问题是它只返回<endpoint>节点中的1个。

例如,我可以有这个片段的xml:

<service name="a"> 
<endpoint>1</endpoint> 
<endpoint>2</endpoint> 
<endpoint>3</endpoint> 
</service> 
<service name="b"> 
<endpoint>1</endpoint> 
<endpoint>2</endpoint> 
</service> 

每次我得到一个比赛,我希望它显示所有的那场比赛的<endpoint>子节点。

这是我到目前为止的代码:

 IEnumerable<XElement> xmlURL = 
      from el in xmlFile.Root.Descendants("service") 
      where (string)el.Attribute("name") == serviceString 
      select el.Element("endpoint"); 

     Console.WriteLine("Start: " + serviceString); 
     foreach (XElement el in xmlURL) 
     { 
      Console.WriteLine(el); 
     } 
     Console.WriteLine("End: " + serviceString + "\n\n"); 

目前,当它的比赛只有1个端点所示。

回答

6

我想你想要这样的:

IEnumerable<XElement> xmlURL = 
     from el in xmlFile.Root.Descendants("service") 
     where (string)el.Attribute("name") == serviceString 
     select el.Descendants("endpoint"); 

    Console.WriteLine("Start: " + serviceString); 
    foreach (XElement el in xmlURL) 
    { 
     Console.WriteLine(el); 
    } 
    Console.WriteLine("End: " + serviceString + "\n\n"); 

请注意,我选择el.Descendants()而不是Element()这将只返回第一个匹配(http://msdn.microsoft.com/en-us/library/system.xml.linq.xcontainer.element.aspx)。

** UPDATE **

我想这是你想要的,因为你只能有一个具体比赛conerned。

IEnumerable<XElement> xmlURL = 
    (from el in doc.Root.Descendants("service") 
    where el.Attribute("name").Value == serviceString 
    select el).First().Descendants(); 

所以LINQ查询的结果是,因为编译器会告诉你,IEnumerables的IEnumerable,所以我采取First()结果是给了我现在的IEnumerable<XElement>,然后我们呼吁Descendants(),这为您提供IEnumerable的端点XElement's。

还要注意这里我使用了XAttributeValue财产,你不能简单地把XAttribute为字符串,你必须使用Value属性。我没有在最初的复制/粘贴答案中看到。

** 更新2 **

上述查询可以是可能有点容易理解是这样的:

doc.Root.Descendants("service") 
    .Where(x => x.Attribute("name").Value == serviceString) 
    .First() 
    .Descendants(); 

** 更新3 **

有也是NRE在属性匹配上的潜力,所以再次这可能是一个甚至更​​好的版本。 =)

doc.Root.Descendants("service") 
    .Where(x => x.Attribute("name") != null && x.Attribute("name").Value == serviceString) 
    .First() 
    .Descendants(); 
+1

在这种情况下,当只有一个孩子的级别,后代会没事的。否则,您可能想要使用仅返回直接子项的元素(XName)。 –

+0

@JoachimIsaksson好点。 – CodingGorilla

+0

当我尝试使用后代时出现以下错误: 无法将类型'System.Collections.Generic.IEnumerable >'隐式转换为' System.Collections.Generic.IEnumerable ”。存在明确的转换(您是否缺少演员?) – webdad3