Subject: Looping through attributes in an XML document
Posted By: francislang Post Date: 11/16/2004 8:47:52 AM
I'm trying to find a neat way of looping through an XML document so that I can get the attributes and the relevant values so that I can save them.

The only way i've managed to do this so far is nesting loops inside each other. One loop for each level. This seems a bit restrictive though. What if another level were to appear in the document?

Here's my code:

For Each Node In myNodeList
    If Node.HasChildNodes Then
        For Each childNode In Node
            logIt.dBug(childNode.Name)
               For Each Attribute In childNode.Attributes
                    saveAttribute(Attribute.Name, Attribute.Value)
               Next
               If childNode.HasChildNodes Then
                     For Each nextChildNode In childNode
                         logIt.dBug(nextChildNode.Name)
                             For Each Attribute In nextChildNode.Attributes
                                 saveAttribute(Attribute.Name, Attribute.Value)
                             Next
                     Next
              End If
         Next
    End If
Next

Any ideas would be greatly appreciated.

Many thanks,

Francis

Reply By: joefawcett Reply Date: 11/16/2004 9:03:03 AM
Sounds like you need recursion.
Pseudo code:


function saveAttribute(Name, Value)

function saveAttributes(Node)
{
  loop through attributes and call saveAttribute for each one
  if Node has children loop through children and call saveAttributes passing in each node
}

function main()
{
  get document element and call saveAttributes(documentElement)
}

main()


--

Joe (Microsoft MVP - XML)
Reply By: mhkay Reply Date: 11/16/2004 9:12:00 AM
The classic way to walk a tree is with a recursive function. In pseudocode:

function processElement(Element e) {
  doSomethingWith(e);
  for each child c of e {
     processElement(c)
  }
}



Michael Kay
http://www.saxonica.com/
Reply By: francislang Reply Date: 11/17/2004 8:57:07 AM
Thanks for your comments.

I have attempted a structure similar to your advice, but I am receiving a peculiar outcome.

I have a loop that goes through a nodlist:

For Each node In NodeList
   saveNodeAttributes(node)
Next node

Then setup the other function for the recursion:

Public Sub saveNodeAttributes(ByVal Node As Xml.XmlNode)
        Dim attribute As Xml.XmlAttribute
        If Not Node.Attributes Is Nothing Then
            For Each attribute In Node.Attributes
                logIt.dBug(attribute.Name)
            Next attribute
        End If
        
        If Node.HasChildNodes Then
            saveNodeAttributes(Node.FirstChild)
        ElseIf Not Node.NextSibling Is Nothing Then
            saveNodeAttributes(Node.NextSibling)
        ElseIf Not Node.ParentNode.NextSibling Is Nothing Then
            saveNodeAttributes(Node.ParentNode.NextSibling)
        End If
    End Sub

It checks to see if the node has any "children", if it does then select the "firstchild". If not check if there are any "siblings", if not then go back to the "parent" and choose the next sibling.

This however is outputting the 2nd half of the document's attributes twice?

Any idea what could be wrong?

Thanks,

Francis

Reply By: joefawcett Reply Date: 11/17/2004 10:02:39 AM
You don't need to worry about siblings and parents.



--

Joe (Microsoft MVP - XML)

Go to topic 22210

Return to index page 713
Return to index page 712
Return to index page 711
Return to index page 710
Return to index page 709
Return to index page 708
Return to index page 707
Return to index page 706
Return to index page 705
Return to index page 704