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>[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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您当前的查询返回
List>
。这意味着您需要两个嵌套的foreach
循环:一个用于循环列表,另一个用于循环IEnumerable
的内容。相反,您可以更新 LINQ 查询以使用
Enumerable.SelectMany
方法并直接获取地址。在查询格式中,SelectMany
通过使用第二个from
子句来表示,以指示子查询。这类似于以下内容:此外,如果您只想迭代结果并且不打算将结果用作列表用于其他目的,则不需要
ToList
。编辑:为了解释此查询的工作原理,让我们将其分为两部分:
第一:
此查询所有
节点,并且仅匹配具有 < em>group “FooBar”的属性值。第二:
这是一个子查询,在第一部分(上面)结束的地方继续。它本质上是一种进一步查询原始查询结果的方法。在这里,我们查询所有
节点,最后为节点的内部文本选择它们的
Value
。我们需要这样做的原因是Descendants("Address")
返回一个包含所有“Address”元素的IEnumerable
。我们需要执行额外的查询(或 foreach)来迭代这些值并提取它们的值。说明这一点的另一种方法是将其分解为 2 个查询:
请注意
query2
中使用SelectMany
。query2
中的Select
是对我之前提到的IEnumerable
进行循环的额外工作。原始查询比 query1/query2 更清晰,但我编写它们只是为了澄清这一点。Your current query returns a
List<IEnumerable<XElement>>
. That means you need two nestedforeach
loops: one to loop over the list, and another to loop over the content of theIEnumerable<XElement>
.Instead, you could update your LINQ query to use the
Enumerable.SelectMany
method and get to the addresses directly. In query format aSelectMany
is represented by using a secondfrom
clause to indicate a subquery. This would resemble the following:Also, the
ToList
isn't needed if you only want to iterate over the results and don't intend to use the result as a list for other purposes.EDIT: to explain how this query works let's break it down in 2 parts:
First:
This queries for all
<Email>
nodes and only matches the ones that have a group attribute value of "FooBar".Second:
This is a subquery that continues where the first part (above) ended. It essentially is a way to further query the results of the original query. Here we query for all
<Address>
nodes and, finally, select theirValue
for the inner text of the nodes. The reason we need to do this is becauseDescendants("Address")
returns aIEnumerable<XElement>
containing all "Address" elements. We need to perform an additional query (orforeach
) to iterate over those values and extract their values.Another way to illustrate this is by breaking it down in 2 queries:
Notice the use of
SelectMany
inquery2
. TheSelect
inquery2
is that additional effort to loop over theIEnumerable
that I mentioned earlier. The original query is clearer than query1/query2, but I wrote them just to clarify the point.