David.Warwick
David.Warwick

Reputation: 750

VBA IXMLDOMNode.hasChildNodes not working correctly for me

This seems like it should be easy, but it is not working as expected. First, I will post the XML and then the VBA that I have. Unfortunately, I cannot post the entire XML file.

-<item id="ref4">
    <paratext>Reinstall tire retainers, if applicable.</paratext>
</item>-
<item>-
    <paratext>
       Repeat steps 
     <xref xrefid="ref3"/>
       . through 
     <xref xrefid="ref4"/>. 
       for remaining wheel.</paratext>
</item>-
<item>
    <paratext>Apply thick coat of grease to wheel shafts.</paratext>
</item>-
<item>
    <paratext>Remove gloves and then goggles.</paratext>
</item>
Dim xmlDoc As New DOMDocument
Dim n As IXMLDOMNode
'ProcSteps
    For Each n In xmlDoc.selectNodes("//procsteps/seqlist/item/paratext")
Debug.Print strSYSCOM, n.hasChildNodes, n.Text
        If n.hasChildNodes = False Then ' does this step reference other steps? If so, we don't need to process it.
            If HasNumber(n.Text) Then
                rsSteps.AddNew
                    rsSteps!MRC_ID = lngMRCID
                    rsSteps!txtStep = n.Text
                rsSteps.Update
            End If
        End If
    Next
End If

So basically what I am trying to determine is whether or not xref tags exist within the paratext tags. If they do, then I don't want to process the paratext tags. And, I need to do this as efficiently as possible because I have thousands of XML documents to process.

When I print n.text as shown above, I get

Repeat steps . through . for remaining wheel.

So it seems to me that xref is not a child node of paratext. And in fact, I haven't run across a situation yet where haschildnodes has been false. So, what am I missing? David

Upvotes: 0

Views: 782

Answers (1)

David Zemens
David Zemens

Reputation: 53623

A child node is not a child element. The text values of each element are also considered "nodes".

Why not simply use the XPATH to do this?

Sub foo()

Dim xml_string As String
Dim n As Object 'IXMLDomNode
Dim c as Object 'IXMLDomNode
Dim nodes As Object 'IXMLDomNodeList
Dim xmlDoc As Object 'MSXML2.DomDocument

xml_string = "<paratext>Repeat steps" & _
      "<xref xrefid='ref3'/>" & _
      " .through" & _
      "<xref xrefid='ref4'/>." & _
      "  for remaining wheel.</paratext>"


Set xmlDoc = CreateObject("MSXML2.DomDocument")

xmlDoc.LoadXML xml_string

Set nodes = xmlDoc.SelectNodes("//paratext")

For Each n In nodes
    If n.SelectNodes("//xref") Is Nothing Then
        'Process this PARATEXT node
        MsgBox "process!"
    Else
        'There ARE child nodes of /xref tagname, so skip this node
        'do nothing
        MsgBox "/xref child nodes exist, not processed!" & vbCrLf & vbCrLf & n.XML

    End If

Next

End Sub

Observe that if the nodes specified by the xpath parameter do not exist:

Set nodes = xmlDoc.SelectNodes("//paratext/Hulk_Hogan")

The For / Each loop will skip, since the nodes NodeList will be an empty collection. You can even test for this (if you want) by doing nodes.Length which will return 0 value when there are no matching nodes.

Upvotes: 1

Related Questions