问题
I am probably making some kind of stupid mistake here, but I'm stuck, so hopefully some of you can help me out.
I Have loaded an XML to xmlDoc through post, using DOMDocument and XMLHTTP
Set xmlhtp = CreateObject("MSXML2.XMLHTTP.6.0")
Set xmlDoc = CreateObject("MSXML2.DOMDocument.6.0")
When I recieve the response from the API I write it to a cell to check the response, and it loads there. I find my Nodes and my information. I write it to a cell with
With xmlhtp
.Open "post", sURL, False
.setRequestHeader "Host", "Host-name"
.setRequestHeader "Content-Type", "text/xml;charset=UTF-8"
.setRequestHeader "soapAction", "action-ID"
.send sEnv
xmlDoc.LoadXML .responseText
Worksheets("Ark1").Range("A11").Value = .responseText
MsgBox (xmlDoc.SelectSingleNode("//ExternalReference"))
In my dump to A11 I find the node ExternalReference, and it has info in it, see screenshot
But even though everything seems fine, the MsgBox does not find the Node. I get the "Object Variable or With block variable not set"-error message.
I tried to add all xmlns-URLs from the response I get in SoapUI, but that did not help with anything.
I have also tried to loop through the parent node of this node (case) with a sequence I know works in another code I have (after some help yesterday here (not the same script or XML this time though):
How to loop through XML-nodes and validate if values exists?)
The loop I tried to run, it does not produce any content either (seems like it cannot find the nodes in the XML)
Const MAX_AR As Long = 3
Dim Casep, Casec, c As Range, i As Long
Set c = Worksheets("Ark1").Range("J1")
Set Casep = xmlDoc.getElementsByTagName("Case")
For Each Casec In Casep
c.Offset(0, i) = Casec.getElementsByTagName("AccountName")(0).Text
c.Offset(1, i) = Casec.getElementsByTagName("ContractName")(0).Text
c.Offset(2, i) = Casec.getElementsByTagName("ExternalReference")(0).Text
i = i + 1
If i >= MAX_AR Then Exit For 'Hopp ut ved oppnådd Max År
Next Casec
It it helps, here is a scrubbed part of the XML:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ResponseHeader xmlns:h="URL to schema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<QueueId i:nil="true" xmlns="URL to schema"/>
<SessionId xmlns="URL to schema">123456789</SessionId>
</h:ResponseHeader>
</s:Header>
<s:Body>
<CaseGetResponse xmlns="URL to schema">
<Case xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<AccountName>123456</AccountName>
<ContractName>123456</ContractName>
<ExternalReference>extref</ExternalReference>
<ExternalReference2 i:nil="true"/>
<ExternalReferences/>
<ExternalSystemReference i:nil="true"/>
<Sequence>654321</Sequence>
回答1:
Adding namespaces fixes the xpath query (but I'm not sure the getElementsByTagName
cares about them)
Dim xmlDoc As New MSXML2.DOMDocument
Dim cases, cs
'need these next two....
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.setProperty "SelectionNamespaces", _
"xmlns:s='http://schemas.xmlsoap.org/soap/envelope/' " & _
"xmlns:i='http://www.w3.org/2001/XMLSchema-instance' " & _
"xmlns:xx='http://URL/to/schema' "
xmlDoc.LoadXML Range("A1").Value 'loading from a worksheet...
'this works with the dummy namespace reference
Debug.Print xmlDoc.DocumentElement.SelectNodes("//xx:ExternalReference")(0).Text '>>extref
'also works
Set cases = xmlDoc.getElementsByTagName("Case")
For Each cs In cases
Debug.Print cs.getElementsByTagName("AccountName")(0).Text
Debug.Print cs.getElementsByTagName("ContractName")(0).Text
Debug.Print cs.getElementsByTagName("ExternalReference")(0).Text
Next cs
As for why the inherited namespace prefix on <ExternalReference>
is xx
and not i
, see the accepted response here: XML: do child nodes inherit parent's namespace prefix?. Basically prefixed namespaces are not inherited but un-prefixed ones ("default namespaces", declared using xmlns="..."
) are: in this case <ExternalReference>
gets its namespace from <CaseGetResponse>
not <Case>
FYI I was using this XML (note I adjusted your dummy namespace URL):
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ResponseHeader xmlns:h="URL to schema"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<QueueId i:nil="true" xmlns="URL to schema"/>
<SessionId xmlns="URL to schema">123456789</SessionId>
</h:ResponseHeader>
</s:Header>
<s:Body>
<CaseGetResponse xmlns="http://URL/to/schema">
<Case xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<AccountName>123456</AccountName>
<ContractName>123456</ContractName>
<ExternalReference>extref</ExternalReference>
<ExternalReference2 i:nil="true"/>
<ExternalReferences/>
<ExternalSystemReference i:nil="true"/>
<Sequence>654321</Sequence>
</Case>
</CaseGetResponse>
</s:Body>
</s:Envelope>
来源:https://stackoverflow.com/questions/64901392/nodes-in-xml-does-not-appear-to-be-identified-utilizable