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 です! ページには何も書き込まれません。奇妙なことの 1 つは、ルート要素を選択してその長さを次のように取得した場合です。

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

それが「うまくいかない」場合は、そう言ってください。次に、より長い回答を提供しようとします。

(簡単な回答への追記: XML を 2 回変換しないというAnthonyWJones のアドバイスは適切です。一般的に適用可能な戦略としてではなく、OT が最初のハードルを乗り越えることを期待して、この「既存のコードへの影響を最小限に抑える」アプローチを提案しました。)

より長い答え

ASP ページで XML の問題が発生した場合は、コンソール スクリプトで XML 固有の問題を切り分けてテストする必要があります。あなたの問題のために、XPathおよびDOMツリーを介してノードにアクセスするためのコードでスケルトン(.xmlファイルをロードし、エラーをチェック)を埋めました:

  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 を使用して、整形式/有効/使用可能なドキュメントを取得したかどうかを確認します)
  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は大文字と小文字を区別するため、取得しているxmlが取得していると思っていたものと一致しなかったため、XPath(Ekkehardがすでに指摘した.textグーフを除く)は機能しません。

最後に、「キャメル ケーシング」の定義はさまざまですが、一般に、この「postalAddress」はキャメル ケースであり、この「PostalAddress」は「Pascal ケーシング」と呼ばれます。

于 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 に答える