XML 中的节点似乎无法识别/可用 [英] Nodes in XML does not appear to be identified/utilizable
问题描述
我可能在这里犯了一些愚蠢的错误,但我被卡住了,所以希望你们中的一些人可以帮助我.
I am probably making some kind of stupid mistake here, but I'm stuck, so hopefully some of you can help me out.
我已经使用 DOMDocument 和 XMLHTTP 通过 post 将 XML 加载到 xmlDoc
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")
当我收到来自 API 的响应时,我将其写入一个单元格以检查响应,并在那里加载.我找到了我的节点和我的信息.我把它写到一个单元格中
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"))
在我到 A11 的转储中,我找到了节点 ExternalReference,其中包含信息,请参阅屏幕截图
In my dump to A11 I find the node ExternalReference, and it has info in it, see screenshot
但是即使一切看起来都很好,MsgBox 还是没有找到节点.我收到对象变量或未设置块变量"错误消息.
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.
我尝试从我在 SoapUI 中得到的响应中添加所有 xmlns-URL,但这没有任何帮助.
I tried to add all xmlns-URLs from the response I get in SoapUI, but that did not help with anything.
我还尝试使用我知道在我拥有的另一个代码中工作的序列遍历此节点(案例)的父节点(经过昨天的一些帮助(尽管这次不是相同的脚本或 XML):
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):
我尝试运行的循环,它也不产生任何内容(似乎在 XML 中找不到节点)
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
它有帮助,这里是 XML 的一个擦洗部分:
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>
推荐答案
添加命名空间修复了 xpath 查询(但我不确定 getElementsByTagName
是否关心它们)
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
至于为什么 <ExternalReference>
上继承的命名空间前缀是 xx
而不是 i
,请参阅此处接受的回复:xmlns=..."
声明)是:在这种情况下
从
而非
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>
仅供参考,我使用的是这个 XML(注意我调整了你的虚拟命名空间 URL):
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>
这篇关于XML 中的节点似乎无法识别/可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!