我试图从某些webservice响应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.为什么!
请注意,这不是我尝试访问这些节点值的唯一方法。我无法弄清楚我做错了什么。请有人帮帮我。干杯。
答案 0 :(得分:2)
简短回答
oXMLHttp.ResponseXML.text可能会返回一些文本,但不会返回“包含指定XML文件位置的URL的字符串”,这是.load参数所需的。所以替换
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 :(得分: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 goof)不会起作用,因为你得到的xml与你认为的不一致得到了。
最后“Camel casing”的定义确实有所不同,但一般来说这个“postalAddress”是骆驼套装,而这个“PostalAddress”被称为“Pascal套管”。
答案 2 :(得分: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'属性输出显示标记为camel case。因此,ResponseXML相当误导,并且看到XPath区分大小写阻止我选择有问题的节点。