linq到xml枚​​举后代

时间:2011-01-13 15:13:08

标签: vb.net linq-to-xml

你试着从我读过的教程中写一个简单的linq查询。但我似乎无法让它发挥作用。我试图在附加的xml文档中显示两个地址,但只能显示第一个。有人可以帮我弄清楚为什么两个都不打印。非常感谢你

<?xml version="1.0" encoding="utf-8" ?>
<Emails>
  <Email group="FooBar">
    <Subject>Test subject</Subject>
    <Content>Test Content</Content>
    <EmailTo>
      <Address>foo@bar.com</Address>
      <Address>bar@foo.com</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

1 个答案:

答案 0 :(得分: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))

请注意SelectMany中使用query2Select中的query2是我在前面提到的IEnumerable循环的额外工作。原始查询比query1 / query2更清晰,但我写这些只是为了澄清这一点。