XML中的节点似乎未被识别/可利用 [英] Nodes in XML does not appear to be identified/utilizable

查看:59
本文介绍了XML中的节点似乎未被识别/可利用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我已经使用DOMDocument和XMLHTTP通过邮政将XML加载到xmlDoc

  Set xmlhtp = CreateObject("MSXML2.XMLHTTP.6.0")设置xmlDoc = CreateObject("MSXML2.DOMDocument.6.0") 

当我从API收到响应时,将其写入到单元格中以检查响应,然后将其加载到该单元格中.我找到了我的节点和信息.我用

将其写到一个单元格中

 使用xmlhtp.打开"post",sURL,False.setRequestHeader主机",主机名".setRequestHeader"Content-Type","text/xml; charset = UTF-8";.setRequestHeader"soapAction","action-ID".send sEnvxmlDoc.LoadXML .responseText工作表("Ark1").Range("A11").Value = .responseTextMsgBox(xmlDoc.SelectSingleNode("//ExternalReference")) 

在转储到A11的过程中,我找到了节点ExternalReference,并且其中包含信息,请参见屏幕截图.

但是,尽管一切似乎都很好,但MsgBox找不到节点.我收到对象变量或未设置块变量"错误消息.

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

我还尝试用我知道的序列在我拥有的另一个代码中工作的顺序遍历该节点(案例)的父节点(经过昨天的一些帮助(尽管这次不是同一脚本或XML):

如何遍历XML节点并验证值是否存在?)

我尝试运行的循环,它也不产生任何内容(似乎无法在XML中找到节点)

  Const MAX_AR as Long = 3昏暗的Casep,Casec,c为范围,我为设置c = Worksheets("Ark1").Range("J1")设置Casep = xmlDoc.getElementsByTagName("Case")对于Casep中的每个Casecc.Offset(0,i)= Casec.getElementsByTagName("AccountName")(0).Textc.Offset(1,i)= Casec.getElementsByTagName("ContractName")(0).Textc.Offset(2,i)= Casec.getElementsByTagName("ExternalReference")(0).Text我=我+ 1如果i> = MAX_AR,则退出最大操作数"下一个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到模式"/>< SessionId xmlns ="URL到架构"> 123456789</SessionId></h:ResponseHeader></s:Header>< s:Body>< CaseGetResponse xmlns ="URL到模式">< Case xmlns:i =" http://www.w3.org/2001/XMLSchema-instance>< AccountName> 123456</AccountName><合约名称> 123456</合约名称>< ExternalReference> extref</ExternalReference>< ExternalReference2 i:nil ="true"/><外部参考/>< ExternalSystemReference i:nil ="true"/><序列> 654321</序列> 

解决方案

添加名称空间可修复xpath查询(但我不确定 getElementsByTagName 是否关心它们)

 将xmlDoc设为新的MSXML2.DOMDocument昏暗的情况下,cs需要接下来的两个....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").从工作表中加载值'...'这适用于虚拟名称空间参考Debug.Print xmlDoc.DocumentElement.SelectNodes("//xx:ExternalReference")(0).Text'>> extref'也有效设置案例= xmlDoc.getElementsByTagName("Case")对于每个cs在情况下Debug.Print cs.getElementsByTagName("AccountName")(0).TextDebug.Print cs.getElementsByTagName("ContractName")(0).TextDebug.Print cs.getElementsByTagName("ExternalReference")(0).Text下一个cs 

关于为什么< ExternalReference> 上继承的名称空间前缀是 xx 而不是 i 的原因,请参见此处的已接受响应: XML:子节点是否继承父节点的名称空间前缀?.基本上没有前缀的名称空间是继承的,但无前缀的名称空间(默认名称空间",使用 xmlns ="..." 声明)是:在这种情况下,< ExternalReference> < CaseGetResponse> 获取其名称空间,而不是< Case>

仅供参考,我正在使用此XML(请注意,我已经调整了您的虚拟名称空间URL):

 <?xml version ="1.0"?>< s:信封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到模式"/>< SessionId xmlns ="URL到架构"> 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><合约名称> 123456</合约名称>< ExternalReference> extref</ExternalReference>< ExternalReference2 i:nil ="true"/><外部参考/>< ExternalSystemReference i:nil ="true"/><序列> 654321</序列></Case></CaseGetResponse></s:Body></s:信封> 

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>

解决方案

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>

这篇关于XML中的节点似乎未被识别/可利用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆