XML 中的节点似乎不是 identified/utilizable

Nodes in XML does not appear to be identified/utilizable

我可能在这里犯了一些愚蠢的错误,但我被卡住了,所以希望你们中的一些人能帮助我。

我已经使用 DOMDocument 和 XMLHTTP

通过 post 将 XML 加载到 xmlDoc
Set xmlhtp = CreateObject("MSXML2.XMLHTTP.6.0")
Set xmlDoc = CreateObject("MSXML2.DOMDocument.6.0")

当我收到来自 API 的响应时,我将其写入一个单元格以检查响应,并将其加载到那里。我找到我的节点和我的信息。我用

将它写入一个单元格
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,其中包含信息,请参见屏幕截图

但是即使一切看起来都很好,MsgBox 也没有找到节点。我收到“未设置对象变量或块变量”错误消息。

我尝试从我在 SoapUI 中获得的响应中添加所有 xmlns-URL,但这对任何事情都没有帮助。

我还尝试使用我知道在我拥有的另一个代码中工作的序列遍历此节点(案例)的父节点(在昨天这里的一些帮助之后(不是相同的脚本或 XML 这个虽然时间):

)

我试过的循环运行,它也不产生任何内容(好像找不到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 的擦洗部分:

<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 关心它们)

    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,请参阅此处接受的响应:XML: do child nodes inherit parent's namespace prefix?。基本上带前缀的命名空间不会被继承,但没有前缀的命名空间(“默认命名空间”,使用 xmlns="..." 声明)是:在这种情况下,<ExternalReference><CaseGetResponse> 而不是 <Case> 获取其命名空间

仅供参考,我正在使用这个 XML(注意我调整了你的虚拟命名空间 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>