0

我试图从一些 web 服务响应 XML 中选择节点无济于事。出于某种原因,我能够选择根节点(“xmldata”)但是,当我尝试更深入地钻取(“xmldata/customers”)时,一切都返回为空!以下是 Web 服务返回的 XML 示例。

<xmldata>
  <customers>
    <customerid>22506</customerid>
    <firstname>Jim</firstname>
    <issuperadmin>N</issuperadmin>   
    <lastname>Jones</lastname>
  </customers>
</xmldata>

这是我试图选择 customerid、firstname 和 lastname 的代码;

' Send the Xml
oXMLHttp.send Xml_to_Send

' Validate the Xml
dim xmlDoc
set xmlDoc = Server.CreateObject("Msxml2.DOMDocument")
xmlDoc.load (oXMLHttp.ResponseXML.text)
if(len(xmlDoc.text) = 0) then
    Xml_Returned = "<B>ERROR in Response xml:<BR>ERROR DETAILS:</B><BR><HR><BR>" 
end if

dim nodeList
Set nodeList = xmlDoc.SelectNodes("xmldata/customers")

For Each itemAttrib In nodeList
    dim custID, custLname, custFname    
    custID =itemAttrib.selectSingleNode("customerid").text
    custLname =itemAttrib.selectSingleNode("lastname").text
    custFname =itemAttrib.selectSingleNode("firstname").text
    response.write("News Subject: " & custID)
    response.write("<br />News Subject: " & custLname)
    response.write("<br />News Date: " & custFname)
Next

上面代码的结果是 zilch!页面上没有写入任何内容。一件奇怪的事情是,如果我选择根元素并得到它的长度,如下所示;

Set nodeList = xmlDoc.SelectNodes("xmldata")
Response.Write(nodeList.length) '1 is written to page

它正确地确定了 1 的长度。但是,当我尝试对下一个节点进行相同操作时,如下所示;

Set nodeList2 = xmlDoc.SelectNodes("xmldata/customers")
Response.Write(nodeList.length) '0 is written to page

它返回长度为 0。为什么!

请注意,这不是我尝试访问这些节点值的唯一方法。我只是无法弄清楚我做错了什么。有人可以帮我吗。干杯。

4

3 回答 3

2

简短的回答

oXMLHttp.ResponseXML.text 可能会返回一些文本,但不是 .load 参数所需的“包含指定 XML 文件位置的 URL 的字符串”。所以更换

xmlDoc.load (oXMLHttp.ResponseXML.text)

xmlDoc.loadXml oXMLHttp.ResponseXML.xml

如果那“行不通”,请说出来;然后,我将尝试提供更长的答案。

(对简短回答的 PS:AnthonyWJones 的建议不要转换 XML 两次是合理的;我提供了这种“对现有代码影响最小”的方法,希望让 OT 克服第一个障碍,而不是作为普遍适用的策略。)

更长的答案

如果您在 ASP 页面上遇到 XML 问题,您应该尝试在控制台脚本中隔离和测试特定于 XML 的问题。对于您的问题,我用代码填充了一个框架(加载 .xml 文件,检查错误),以通过 XPath 和 DOM 树访问节点:

  Dim oFS    : Set oFS  = CreateObject( "Scripting.FileSystemObject" )
  Dim sFSpec : sFSpec   = oFS.GetAbsolutePathName("..\data\00.xml")
  Dim oXml   : Set oXml = CreateObject("Msxml2.DOMDocument")

  oXml.setProperty "SelectionLanguage", "XPath"
  oXml.async = False
  oXml.load sFSpec

  If 0 = oXml.parseError.errorCode Then
     WScript.Echo "loaded:", sFSpec
     WScript.Echo "root:", oXml.documentElement.tagName

     Dim sXPath, ndlFnd, ndChild, ndFnd

     sXPath = "/xmldata/customers"
     Set ndlFnd = oXml.selectNodes(sXPath)
     If 0 = ndlFnd.length Then
        WScript.Echo "no '" & sXPath & "' found"
     Else
        WScript.Echo "found", ndlFnd.length, "node(s) for '" & sXPath & "'"
        sXPath = "firstname"
        For Each ndChild In ndlFnd
            WScript.Echo "child:", ndChild.tagName
            Set ndFnd = ndChild.selectSingleNode(sXPath)
            If ndFnd Is Nothing Then
               WScript.Echo "no '" & sXPath & "' found"
            Else
               WScript.Echo ndFnd.text, "==", ndChild.childNodes(1).text
            End If
        Next
     End If
  Else
     WScript.Echo "errorCode:", oXml.parseError.errorCode
     WScript.Echo oXml.parseError.reason
  End If

输出:

loaded: E:\trials\SoTrials\answers\11166940\data\00.xml
root: xmldata
found 1 node(s) for '/xmldata/customers'
child: customers
Jim == Jim

如你看到的

  1. 我使用标准/批准的方法来检查单个步骤的结果(例如 parseError(而不是 voodoo 长度测试)以查看我是否得到了格式正确/有效/可用的文档)
  2. 如有疑问,我会放入 WScript.Echo 以确保我对 VBScript 应该提供的假设是否成立。
于 2012-06-23T06:08:26.290 回答
2

首先停止这样做:

Dim doc : Set xmlDoc = CreateObject("MSXML2.DOMDocument")
xmlDoc.LoadXML (oXmlHttp.responseXML.xml)

响应中的 XML 被解析为 DOM,然后您要求将其转换回字符串 (.xml),然后再将其解析为另一个 DOM (.LoadXML)。

只需这样做:

Dim xmlDoc : Set xmlDoc = oXmlHttp.responseXML

其次,您的答案是正确的 XPath 区分大小写,因此您的 XPath(除了 Ekkehard 已经指出的 .text 错误)将无法工作,因为您获得的 xml 与您认为的不匹配。

最后,“骆驼大小写”的定义确实有所不同,但通常这个“邮政地址”是骆驼大小写的,这个“邮政地址”被称为“帕斯卡大小写”。

于 2012-06-23T15:10:17.253 回答
0

好的,所以我终于弄清楚了我做错了什么。由于我正在检索的 xml 来自 web 服务,并且我对它的信息有限,因此我使用以下内容将 xml 写入页面,以便我可以看到它的结构。

Response.Write oXMLHttp.ResponseXml.xml

出于某种原因(也许有人可以填写这部分),它以小写形式编写了所有 XML 标记。事实证明,经过一番调查和以下操作后,我发现这不是事实!

dim nodeList
Set nodeList = xmlDoc.SelectNodes("//xmldata/")

for each item In nodeList
    response.write(item.text & " -> Tag Name: " & item.nodeName & "<br />")
Next

'this wrote the following to the page
'22506 -> Tag Name: CustomerID
'Jim -> Tag Name: FirstName
'N -> Tag Name: IsSuperAdmin
'Jones 2 -> Tag Name: LastName

如您所见,“nodeName”属性输出显示标签为驼峰式。所以 ResponseXML 相当具有误导性,并且看到 XPath 区分大小写使我无法选择有问题的节点。

于 2012-06-23T12:02:19.927 回答