是否可以在For Each语句中包含两个元素?

时间:2013-12-18 21:23:18

标签: vb.net

在下面的代码示例中,我想在同一个aNode循环中遍历eNodeForFor Each语句中是否可以包含两个元素?以下是不正确的语法,但我在论坛上寻求帮助:

For Each aNode As XmlNode In aDoc.SelectNodes("//*")
     And eNode As XmlNode In eDoc.SelectNodes("//*")

我需要比较两个XmlDocuments以确保它们是相同的。我想为此任务使用单个For Each循环。 aNode是实际的xml结果,eNode是预期的xml结果。 aNode和{}}中的节点/值配对都需要相同。 eNode。节点/值配对在运行时都是未知的,因此我无法对节点发出任何请求,然后查找该值。

2 个答案:

答案 0 :(得分:2)

您应该能够使用LINQ's Concat来组合两个集合,然后您可以迭代这些集合:

For Each node As XmlNode In _
    aDoc.SelectNodes("//*").Cast(Of XmlNode)().Concat( _
        eDoc.SelectNodes("//*").Cast(Of XmlNode)())

或者,为了使其可读:

Dim l_aNodes = aDoc.SelectNodes("//*").Cast(Of XmlNode)()
Dim l_eNodes = eDoc.SelectNodes("//*").Cast(Of XmlNode)()
Dim l_allNodes = l_aNodes.Concat( l_eNodes )

For Each l_node in l_allNodes

这将获取第一个集合中的所有元素,然后将第二个集合中的所有元素附加到它的末尾(如队列)。

或者,如果您想要“zip”,可以使用Enumerable.Zip

If Not l_aNodes.Count = l_eNodes.Count Then
    ...
End If

Dim l_allNodes = 
    Enumerable.Zip( 
        l_aNodes, 
        l_eNodes, 
        Function(a, e) New With { .aNode = a, .eNode = e } )
For Each l_aeNode in l_allNodes
    If Not l_aeNode.aNode.Name = l_aeNode.eNode.Name Then
        ...

根据Enumerable.Zip的文档,

  

如果序列没有相同数量的元素,则该方法会合并序列,直到它们到达其中一个序列的末尾。例如,如果一个序列有三个元素而另一个序列有四个,则结果序列只有三个元素。

因此,您需要在开始之前比较集合大小。这实际上是一个好主意,因为它将节省比较每个节点所需的处理能力。

如果集合大小相同,则上面的代码从每个集合中的第一个元素开始,然后将它们组合成Anonymous Type。然后是每个集合中的第二个元素,然后是第三个元素,等等。结果是匿名类型实例的集合。

然后,您可以迭代匿名类型实例,并使用适当的属性(aNodeeNode)获取每个元素。

但是有一些内置语法来处理这个问题吗?不,没有。

答案 1 :(得分:0)

您可以尝试将节点作为文本存储到已排序的列表中,然后比较列表:

Dim aNodes = New List(Of String)( _
    aDoc _
        .SelectNodes("//*") _
        .[Select](Function(n) n.ToString()) _
        .OrderBy(Function(s) s))
Dim eNodes = New List(Of String)( _
    eDoc _
        .SelectNodes("//*") _
        .[Select](Function(n) n.ToString()) _
        .OrderBy(Function(s) s))

If aNodes.Count <> eNodes.Count Then
    Return False
End If
For i As Integer = 0 To aNodes.Count - 1
    If aNodes(i) <> bNodes(i) Then
        Return False
    End If
Next
Return True