12

I have an XML file from a URL API (the URL I have not shared since it allows access to secure info). From this file I want to get certain info out. My problem is, once I am in the parent node (eventNode) I want to simply be able to get the data from specific child nodes.

For example if eventNode was <event><ID>1</ID>...<title>event 1</title></event>, how would I get 1 from just knowing the node name is ID (or any other value I want to pull out)?

I have looked a lot through forums and the .SelectSingleNode has given me no luck. Also .selectNodes will not act like a normal list of nodes in an XML string. I don't know if this is due to the method I'm using to parse my XML file.

Sub ListEvents()

Dim strPath As String

strPath = getAPI("GetEvents", "filter=&orderBy=")

Dim xmlDocument As MSXML2.DOMDocument60
Set xmlDocument = New DOMDocument60

With CreateObject("MSXML2.XMLHTTP")
    .Open "GET", strPath, False
    .send
    xmlDocument.LoadXML .responseText
End With

Dim lvl1 As IXMLDOMNode: Dim lvl2 As IXMLDOMNode
Dim eventNode As IXMLDOMNode: Dim isNode As IXMLDOMNode

For Each lvl1 In xmlDocument.ChildNodes
    For Each lvl2 In lvl1.ChildNodes
        For Each eventNode In lvl2.ChildNodes
            If eventNode.HasChildNodes Then
                'Here is where I want code to find specific child node
                'without having to look at every node.
            End If
        Next
    Next
Next

End Sub

Sample XML:

<?xml version="1.0" encoding="utf-8" ?> 
<ResultsOfListOfEvent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.regonline.com/api">
  <Success>true</Success> 
  <Data>
    <APIEvent>
      <ID>111</ID> 
      <CustomerID>222</CustomerID> 
      <ParentID>0</ParentID> 
      <Status>Testing</Status> 
      <Title>Event Name</Title> 
      <ClientEventID /> 
      <TypeID>9</TypeID> 
      <TimeZone>GMT</TimeZone> 
      <CurrencyCode>GBP</CurrencyCode> 
      <AddDate>2013-12-18T02:34:09.357</AddDate> 
      <Channel>Running</Channel> 
      <IsWaitlisted>false</IsWaitlisted> 
    </APIEvent>
    <APIEvent>
      <ID>112</ID> 
      <CustomerID>223</CustomerID> 
      <ParentID>0</ParentID> 
      <Status>Testing</Status> 
      <Title>Event Name</Title> 
      <ClientEventID /> 
      <TypeID>9</TypeID> 
      <TimeZone>GMT</TimeZone> 
      <CurrencyCode>GBP</CurrencyCode> 
      <AddDate>2013-12-18T02:34:09.357</AddDate> 
      <Channel>Running</Channel> 
      <IsWaitlisted>false</IsWaitlisted> 
    </APIEvent>
  </Data>
</ResultsOfListOfEvent>

I want to output the text in each <ID> (i.e. 111 and 112) and each <Title>. This is only an example, depending on the API I run I will want to be able to pick and choose what information I pull.

5
  • Post sample xml and expected output Commented Jan 10, 2014 at 14:41
  • Please also post sample output that you are expecting ... as in which child nodes you want to fetch Commented Jan 10, 2014 at 15:02
  • I want to output the text in each (i.e. 111 and 112) and each . This is only an example, depending on the API I run I will want to be able to pick and choose what information I pull. Commented Jan 10, 2014 at 15:08
  • Dynamically search for data In an XML file with VBA Commented Jan 10, 2014 at 15:08
  • Santosh, does this go through every child node? I need to be able to say given x child nodes return the text from <ID> and <Title> without having to look at every single node. I.e. some kind of getNodeText("ID") Commented Jan 10, 2014 at 15:20

2 Answers 2

13

Try this - you can modify the below code to fetch any child node

Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.SetProperty "SelectionLanguage", "XPath"
xmlDoc.Async = False
xmlDoc.Load("C:\Users\pankaj.jaju\Desktop\Test.xml")

Set nodeXML = xmlDoc.getElementsByTagName("ID")
For i = 0 To nodeXML.Length - 1
    MsgBox nodeXML(i).Text
Next

Edit from question author:

This worked great. For any readers this is how I used the answer above to adapt my code (since I load the XML from a URL - not a file):

Sub ListEvents()
Dim myURL As String

myURL = getAPI("GetEvents", "filter=&orderBy=")

Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.async = False

With CreateObject("MSXML2.XMLHTTP")
    .Open "GET", myURL, False
    .send
    xmlDoc.LoadXML .responseText
End With

Set nodeXML = xmlDoc.getElementsByTagName("ID")
For i = 0 To nodeXML.Length - 1
    MsgBox nodeXML(i).Text
Next
End Sub
Sign up to request clarification or add additional context in comments.

2 Comments

+1 @user1559727 for enriching the answer to suit your need and for other users too.
Sorry, where do we input a URL in the second portion of the answer?
11

Here's a slightly different approach that builds on Pankaj Jaju's answer above.

Notes:

  • uses the MSXML2 namespace as the old Microsoft.XMLDOM one is only maintained for legacy support - see here
  • uses the "SelectionNamespaces" property to fix the problem which MSXML2 has with XPath when a document has a default namespace - see here. We create a namespace called r (any name would do though) that has the same URI reference as the default namesepace in the document (http://www.regonline.com/api in this case)
  • uses that new namespace in XPath as the prefix for any element which has an unprefixed name. That's a complicated way of saying that rather than looking for /ID, we'll look for /r:ID

Here is the code:

Sub foo()

Dim xmlDoc As Object
Dim xmlNodeList As Object
Dim xmlNode As Object

Set xmlDoc = CreateObject("MSXML2.DOMDocument.6.0")
xmlDoc.setProperty "SelectionNamespaces", "xmlns:r='http://www.regonline.com/api'"
xmlDoc.async = False
xmlDoc.Load "C:\Users\colin\Desktop\yoz1234.xml"

Set xmlNodeList = xmlDoc.selectNodes("/r:ResultsOfListOfEvent/r:Data/r:APIEvent/r:ID")

For Each xmlNode In xmlNodeList
    MsgBox xmlNode.Text
Next xmlNode

End Sub

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.