2013-12-18 19 views
2

在下面的代碼示例中,我想在同一個For循環中遍歷aNodeeNode。是否可以在For Each聲明中包含兩個元素?以下是不正確的語法,但我在這裏尋求幫助論壇上:是否有可能在For 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

廣東話你窩呢?類似於'blah'中的每個項目,然後'blah2中的每個項目''next'' next' – logixologist

+0

@logixologist - 我認爲OP想要一個扁平列表,但是它會遍歷整個內部列表*外部列表。 – JDB

+1

@JDB,他很難清楚他想要做什麼。你可能是對的。 – logixologist

回答

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)獲取每個元素。

但是有沒有一些內置的語法來處理?不,那裏沒有。

+0

JDB:關於上面的第一個例子,我如何在For循環中執行比較?我可以使用node.FirstChild.ParentNode.Name來檢查節點名稱,但是如何與其他集合中的內容進行比較?這對我來說是完全新的語法。 – scttech

+0

你需要更新你的問題。這是你第一次提到比較任何東西。 – JDB

+0

對不起!我需要比較兩個XmlDocuments以確保它們是相同的。我想爲這個任務使用一個'for each'循環。 aNode是實際的xml結果,eNode是預期的xml結果。節點/值配對在節點和eNode中都需要相同。節點/值配對在運行時都是未知的,所以我不能對節點發出任何請求,然後查找值。 – scttech

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 
相關問題