2013-01-18 85 views
3

我正在尋找一種方法來遍歷我的XML文檔的所有節點。遍歷完整的XML文檔

XML文件樣本

<root> 
    <llnode created="2005-05-24T15:26:24" createdby="42912153" createdbyname="" description="" id="107810306" modified="2008-06-05T16:07:44" name="" objname="" objtype="0" ownedby="42912153" ownedbyname="" parentid="107810295" size="4"> 
     <Nickname domain=""/> 
     <MajorMinorContainer>false</MajorMinorContainer> 
     <llnode created="2005-05-06T12:54:03" createdby="42912153" createdbyname="" description="" id="107815681" modified="2006-12-04T14:39:51" name="" objname="" objtype="0" ownedby="42912153" ownedbyname="" parentid="107810306" size="0"> 
      <Nickname domain=""/> 
      <MajorMinorContainer>false</MajorMinorContainer> 
     </llnode> 
     <llnode created="2005-05-06T12:54:31" createdby="42912153" createdbyname="" description="" id="107815683" modified="2006-12-04T14:39:53" name="" objname="" objtype="0" ownedby="42912153" ownedbyname="" parentid="107810306" size="0"> 
      <Nickname domain=""/> 
      <MajorMinorContainer>false</MajorMinorContainer> 
     </llnode> 
    </llnode> 
    <llnode created="2005-05-24T15:26:24" createdby="42912153" createdbyname="" description="" id="107810306" modified="2008-06-05T16:07:44" name="" objname="" objtype="0" ownedby="42912153" ownedbyname="" parentid="107810295" size="4"> 
     <Nickname domain=""/> 
     <MajorMinorContainer>false</MajorMinorContainer> 
     <llnode created="2005-05-06T12:54:03" createdby="42912153" createdbyname="" description="" id="107815681" modified="2006-12-04T14:39:51" name="" objname="" objtype="0" ownedby="42912153" ownedbyname="" parentid="107810306" size="0"> 
      <Nickname domain=""/> 
      <MajorMinorContainer>false</MajorMinorContainer> 
     </llnode> 
     <llnode created="2005-05-06T12:54:31" createdby="42912153" createdbyname="" description="" id="107815683" modified="2006-12-04T14:39:53" name="" objname="" objtype="0" ownedby="42912153" ownedbyname="" parentid="107810306" size="0"> 
      <Nickname domain=""/> 
      <MajorMinorContainer>false</MajorMinorContainer> 
     </llnode> 
    </llnode> 
</root> 

文件始終具有相同的結構。每個llnode代表一個文件夾。這可能會非常深入(對於上述示例而言,範圍僅爲2,但最高可達10)。

我該如何遍歷所有記錄?我不想把一個循環放到一個循環中,然後再循環一次,然後像這樣做20次,以確保處理每個節點。有沒有辦法做一個循環的循環?

下面是我得到了這麼遠,只工作了實際的XML文檔(範圍= 2),將需要儘可能多的循環添加爲範圍的增加(它不應該走了過來範圍= 10)

原始VBA(從原來的問題)

xmlExportDoc = "myXmlDoc.xml" 

Set xmlDoc = New MSXML2.DOMDocument 
xmlDoc.Load (xmlExportDoc) 

Set xmlNodeList = xmlDoc.SelectNodes("//llnode") 

For Each Node In xmlNodeList 
    MsgBox "Listing the EXISTING nodes" 
    MsgBox Node.nodeName & " " & Node.NodeValue & " " & Node.NodeType 

    If Node.HasChildNodes() Then 
     MsgBox Node.nodeName & "has child nodes" 
     Set xmlNodeList2 = Node.ChildNodes 

     For Each Node2 In oNodeList2 
      MsgBox Node2.nodeName & " " & Node2.NodeValue & " " & Node2.NodeType 

      If Node2.HasChildNodes() Then 
      MsgBox Node2.nodeName & "has child nodes" 
      End If 
     Next 
    End If 
Next 

修訂VBA

Private Function xmlParse(n As MSXML2.IXMLDOMNode) 
    Dim n2 As MSXML2.IXMLDOMNode 
    MsgBox n.nodeName & " " & n.NodeValue & " " & n.NodeType 

    If n.HasChildNodes() Then 
     MsgBox n.nodeName & " has child nodes" 

     For Each n2 In n.ChildNodes 
      xmlParse (n2) 
     Next 

     MsgBox "Done listing child nodes for " & n.nodeName 
    End If 
End Function 

和事件的代碼:

Dim xmlExportDoc As String 
    Dim xmlDoc As MSXML2.DOMDocument 
    Dim xmlNodeList As MSXML2.IXMLDOMNodeList, xmlNodeList2 
    Dim Node As MSXML2.IXMLDOMNode 

    xmlExportDoc = "http://myserver.com/myDoc.xml" 

    Set xmlDoc = New MSXML2.DOMDocument 
    xmlDoc.async = False 
    xmlDoc.Load (xmlExportDoc) 

    Set xmlNodeList = xmlDoc.SelectNodes("//llnode") 

    For Each Node In xmlNodeList 
     Call xmlParse(Node) 
    Next 

這仍然不工作,做遞歸xmlParse()呼叫時,因爲MSXML2.IXMLDOMNode.ChildNodes似乎並沒有成爲一個MSXML2.IXMLDOMNode類型得到了一個錯誤。

回答

6

我想你在這裏需要的是一個遞歸函數。我真的不知道VBA語法,所以請原諒的僞代碼,但你應該能夠做這樣的事情:

Set xmlNodeList = xmlDoc.SelectNodes("/*/llnode") 
For Each node in xmlNodeList 
    ListNodes(node) 
Next 

Function ListNodes(n As Node) 
    MsgBox n.nodeName & " " & n.NodeValue & " " n.NodeType 
    If n.HasChildNodes() Then 
     MsgBox n.nodeName & "has child nodes" 
     For Each n2 in n.ChildNodes 
      ListNodes(n2) 
     Next 
     MsgBox "Done listing child nodes for " & n.nodeName 
    End If 
End Function 
+0

我不知道爲什麼我以前沒有考慮過遞歸性。非常感謝,我會試試這個。任何理由改變// llnode爲/ * /節點? – dnLL

+0

是的,'/ */llnode'選擇頂層'llnodes'。 ''llnode'在一個單一集合中的所有深度處選擇文檔中的所有'llnodes'。 – JLRishe

+0

糟糕,我對XML沒有真正的家喻戶曉,我猜/ llnode和*/llnode也會產生不同的結果。實際上,我上例中的也是。 – dnLL

1

這裏就是我來這麼遠:

xmlExportDoc = "http://www.mysite.com/myDoc.xml" 

Dim xmldoc As MSXML2.DOMDocument 
Dim xmlNode As MSXML2.IXMLDOMNode 
Dim xmlNodeList As MSXML2.IXMLDOMNodeList 
Dim myNode As MSXML2.IXMLDOMNode 

Set xmldoc = New MSXML2.DOMDocument 
xmldoc.async = False 
xmldoc.Load (xmlExportDoc) 
Set xmlNodeList = xmldoc.getElementsByTagName("*") 
On Error Resume Next 
For Each xmlNode In xmlNodeList 
    For Each myNode In xmlNode.ChildNodes 
     'Debug.Print xmlNode.Attributes(0).Text 
    Next myNode 
Next xmlNode 
Set xmldoc = Nothing 

它的工作原理,如果層次結構並不重要,因爲這個腳本只是遍歷節點而不管它是什麼級別的。如果層次很重要,請看JLRishe的答案。