2012-01-26 183 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