【问题标题】:VBScript Can not Select XML nodesVBScript 无法选择 XML 节点
【发布时间】:2012-06-23 04:48:54
【问题描述】:

我试图从一些 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。为什么!

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

【问题讨论】:

    标签: xml asp-classic vbscript msxml


    【解决方案1】:

    首先停止这样做:

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

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

    只需这样做:

    Dim xmlDoc : Set xmlDoc = oXmlHttp.responseXML
    

    其次,你的答案是正确的得到了。

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

    【讨论】:

    • 感谢安东尼的回复。但是,对于导致我的主要问题是为什么所有标签都变成小写的真正问题,我仍然没有答案。我这样说是因为所有已经指出的代码错误实际上都是由于我的实验,它并没有导致问题。附言。会说 Upper Camel Case 安抚了你吗? :)
    • 我不确定您是如何发现“使所有标签都小写”的? MSXML 不这样做。如果你详细描述了准确你是如何观察到这种现象的。
    【解决方案2】:

    简答

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

    xmlDoc.load (oXMLHttp.ResponseXML.text)
    

    xmlDoc.loadXml oXMLHttp.ResponseXML.xml
    

    如果“不起作用”,请说出来;然后我会尝试提供更长的答案。

    (对简短回答的附注:AnthonyWJones 的建议 not 两次转换 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 应该提供的假设是否成立。

    【讨论】:

    • 您好 Ekkerhard,感谢您的回复。我已经尝试了您的建议,但在尝试选择比 xmldata 节点更深的任何内容时仍然遇到同样的问题。
    • 为扩展答案干杯。我发现我的问题与区分大小写有关(我已经发布了详细信息)。下次遇到 XML 问题时,我一定会破解您发布的控制台脚本。
    【解决方案3】:

    好的,所以我终于弄清楚了我做错了什么。由于我正在检索的 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 区分大小写使我无法选择有问题的节点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 2022-08-05
      • 1970-01-01
      相关资源
      最近更新 更多