I am working with a vendor-supplied API that returns this XML when I call it.
<RESPONSE>
<VALID>true</VALID>
<MESSAGE></MESSAGE>
<DATA>
<WORK>
<ROW type="object" class="empty">
<brief_desc>Check plate</brief_desc>
<compid>1354</compid>
<comp_desc>Spitfire #2</comp_desc>
<initials></initials>
<sch_date>2019-10-01</sch_date>
<wo>43351</wo>
<workstatus>O</workstatus>
<work_desc>Check plate for flatness</work_desc>
</ROW>
<ROW type="object" class="empty">
<brief_desc>Check wheel</brief_desc>
<compid>1354</compid>
<comp_desc>Spitfire #1</comp_desc>
<initials></initials>
<sch_date>2019-10-08</sch_date>
<wo>43685</wo>
<workstatus>O</workstatus>
<work_desc>Check wheel for roundness</work_desc>
</ROW>
</WORK>
</DATA>
</RESPONSE>
I call this from another vendor-supplied HMI software, that only supports VBscript. I can get individual values like this, using the Microsoft.XMLDOM object:
xmlDoc.documentElement.selectSingleNode("//VALID").text
However, when I try to get a collection of the "WORK" node, like this...
objNodeList = xmlDoc.getElementsByTagName("DATA")
...I get an error stating "Wrong number of arguments or invalid property assignment". The "DATA" element is all caps, so I think I have the name correct. I have researched this quite a bit, but can't seem to find someone with the exact same issue. I would appreciate any suggestions anyone might have. Thank you!
Edit, adding full code, as requested by people replying to this post:
Function EmaintTest
Dim objRequest
Dim strUrl
Dim strResponse
Dim body
Dim strResponseHeaders
Dim allResponseHeader
Dim xmlDoc
Set objRequest = CreateObject("MSXML2.XMLHTTP")
strUrl = "https://somewebsite.com/wc.dll?x3~api~&q=GetAnyData"
'Set body value as required by API.
body = "{""table"":""WORK"",""columns"":""WO,COMPID,COMP_DESC,WORKSTATUS,BRIEF_DESC,SCH_DATE,WORK_DESC,INITIALS"",""pageNumber"":1,""pageSize"":1000,""filter"":{""logic"":""and"",""filters"":[{""field"":""wo_type"",""operator"":""eq"",""value"":""PM""},{""field"":""COMPID"",""operator"":""eq"",""value"":""1354""},{""field"":""WORKSTATUS"",""operator"":""eq"",""value"":""O""}]},""sortBy"":[{""field"":""SCH_DATE"",""dir"":""asc""}]}"
With objRequest
.Open "POST", strUrl, False
.SetRequestHeader "Cache-Control", "no-cache"
.SetRequestHeader "Content-Type", "text/plain"
.SetRequestHeader "Accept", "application/xml"
.SetRequestHeader "Accept-Encoding", "gzip, deflate, br"
.SetRequestHeader "Connection", "keep-alive"
.Send body
strResponseHeaders = .StatusText
strResponse = .ResponseText
allResponseHeader = .GetAllResponseHeaders
End With
'Load the XML
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.async = False
xmlDoc.loadXML(strResponse)
'Assign variables using the values returned from the API
$Trace (xmlDoc.documentElement.selectSingleNode("//VALID").text ) 'This works, returns "True" value.
Dim xmlNodes
Dim xmlNode
Set xmlNodes = xmlDoc.documentElement.selectNodes("DATA/WORK")
$Trace ("Using selectNodes...")
For Each xmlNode in xmlNodes
$Trace (xmlNode.text)
Next
$Trace ("Using getElementsByTagName...")
Set xmlNodes = xmlDoc.getElementsByTagName("DATA/WORK")
For Each xmlNode In xmlNodes
$Trace (xmlNode.text)
Next
End Function
The issue appears to be with the code that you haven't yet shared. The following code works fine with your XML file. Note that you have the option of using selectNodes or getElementsByTagName.
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.Load ".\Test.xml"
WScript.echo "Using selectNodes..."
Set xmlNodes = xmlDoc.documentElement.selectNodes("DATA/WORK")
For Each xmlNode in xmlNodes
WScript.echo xmlNode.text
Next
WScript.echo "Using getElementsByTagName..."
Set xmlNodes = xmlDoc.getElementsByTagName("DATA/WORK")
For Each xmlNode in xmlNodes
WScript.echo xmlNode.text
Next
Here's a way to traverse all nodes:
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.Load ".\Test.xml"
Set xmlNodes = xmlDoc.selectNodes("//*")
For i = 0 to xmlNodes.length - 1
WScript.Echo xmlNodes(i).nodeName & ": " & xmlNodes(i).text
Next