Loop through a complete XML document
I am looking for a way to iterate over all the nodes of my XML document.
Sample XML file
<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>
The document always has the same structure. Each llnode is a folder. This can be very deep (for the purposes of the above example, the scope is only 2, but it can go up to 10).
How can I iterate over all records? I don't want to insert a loop into a loop and then into another loop and do it like 20 times to access each node. Is there a way to make a loop for loops?
Below is what I got so far, only working on the actual XML document (scope = 2) will need to add as many loops as the scope increases (it shouldn't go through scope = 10)
Original VBA (from the original question)
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
UPDATED 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
And the event code:
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
It still doesn't work, an error occurs when making a recursive call xmlParse()
because it is MSXML2.IXMLDOMNode.ChildNodes
not a type MSXML2.IXMLDOMNode
.
source to share
I think you need a recursive function. I don't really know VBA syntax, so goodbye pseudocode, but you should be able to do something like this:
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
source to share
Here's what I come up with so far:
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
It works if the hierarchy is not important, because this script just goes through nodes of any level. If hierarchy is important, take a look at JLRishe's answer.
source to share