2011-01-13 51 views
1

嗨,試圖從我讀的教程寫一個簡單的linq查詢。但我似乎無法得到它的工作。我試圖在附加的xml文檔中顯示這兩個地址,但只能顯示第一個。有人能幫我弄清楚爲什麼兩者都沒有被打印。非常感謝linq to xml enumerating over descendants

<?xml version="1.0" encoding="utf-8" ?> 
<Emails> 
    <Email group="FooBar"> 
    <Subject>Test subject</Subject> 
    <Content>Test Content</Content> 
    <EmailTo> 
     <Address>[email protected]</Address> 
     <Address>[email protected]</Address> 
    </EmailTo> 
    </Email> 
</Emails> 




    Dim steve = (From email In emailList.Descendants("Email") _ 
       Where (email.Attribute("group").Value.Equals("FooBar")) _ 
       Select content = email.Element("EmailTo").Descendants("Address")).ToList() 



    If Not steve Is Nothing Then 
     For Each addr In steve 
      Console.WriteLine(addr.Value) 
     Next 
     Console.ReadLine() 
    End If 

回答

2

您當前的查詢返回一個List<IEnumerable<XElement>>。這意味着您需要兩個嵌套的foreach循環:一個循環遍歷列表,另一個循環遍歷IEnumerable<XElement>的內容。

相反,您可以更新您的LINQ查詢以使用Enumerable.SelectMany方法並直接到達地址。在查詢格式中,SelectMany通過使用第二個from子句來表示子查詢。這將類似於以下內容:

Dim query = (From email In emailList.Descendants("Email") _ 
      Where (email.Attribute("group").Value.Equals("FooBar")) _ 
      From addr In email.Element("EmailTo").Descendants("Address") _ 
      Select addr.Value).ToList() 

If query.Any() Then 
    For Each addr In query 
     Console.WriteLine(addr) 
    Next 
End If 

而且,不需要ToList如果只想遍歷結果並沒有打算使用結果作爲用於其他目的的列表。

編輯:解釋這種查詢是如何工作的,讓我們打破它分爲兩部分:

第一:

From email In emailList.Descendants("Email") _ 
Where (email.Attribute("group").Value.Equals("FooBar")) _ 

該行查詢所有<Email>節點,只匹配有的那些「FooBar」的屬性值爲

第二:

From addr In email.Element("EmailTo").Descendants("Address") _ 
Select addr.Value 

這是繼續,其中所述第一部分(上文)結束的子查詢。它本質上是一種進一步查詢原始查詢結果的方法。在這裏,我們查詢所有<Address>節點,最後,選擇它們的Value作爲節點的內部文本。我們需要這樣做的原因是因爲Descendants("Address")返回一個包含所有「地址」元素的IEnumerable<XElement>。我們需要執行額外的查詢(或foreach)來遍歷這些值並提取它們的值。

另一種方式來說明這是由它分解在2個查詢:

Dim query1 = From email In emailList.Descendants("Email") _ 
      Where (email.Attribute("group").Value.Equals("FooBar")) 
      Select email.Element("EmailTo").Descendants("Address") 
Dim query2 = query1.SelectMany(Function(addr) addr.Select(Function(a) a.Value)) 

注意在query2使用SelectManyquery2中的Select是額外的努力來循環我前面提到的IEnumerable。原始查詢比查詢1 /查詢2更清晰,但是我只是爲了澄清這一點而寫了它們。

+0

我沒有完全理解你的linq語句是如何工作的。你可以爲我分解它還是指向我可以閱讀的一些資源。我不理解的是第二個從句。這是如何給我我需要的。感謝您的回答和幫助 – gh9 2011-01-13 15:56:33