2012-01-27 27 views
1

我有一個行集使用我的庫存控制系統中的Microsoft行集架構返回。XML行集和MsXML2

但是使用MSXML2時讀取文件我似乎不能夠訪問數據(VBScript編寫)

<xml> 
    <s:schema> 
     <!-- Schema here --> 
    </s:schema> 
    <rs:data> 
     <z:row field="value" field1="value" /> 
    </rs:data> 
</xml> 

要拉這個回我使用:

Set objXmlHttp = Server.CreateObject("Msxml2.ServerXMLHTTP") 
objXmlHttp.open "POST", address, False 
objXmlHttp.setRequestHeader "Content-Type", "text/xml" 
objXmlHttp.Send strXml 

Set objLst = XML_response.getElementsByTagName("data") 
myValue = objLst.item(0).getAttribute("field") 

但是我收到以下消息:

Microsoft VBScript runtime error '800a01a8' 

Object required: 'objLst.item(...)' 

這可能是我做的事情完全WR如果是的話,有人可以指給我看,因爲我現在已經盯着這裏2個小時了,我無法得到它。

+1

我知道這是不是_exactly_你想要什麼,但如果XML是,ADODB記錄使用,你可以加載XML對象直相同的模式到一個記錄集對象:'dim rs:set rs = CreateObject(「ADODB.RecordSet」):rs.open XML_Response' – 2012-01-30 13:33:12

回答

1

給予相同的表:

SELECT TOP 5 * FROM [actor.txt] 
---------------------------------------------------------------- 
|actor_id|first_name|last_name |last_update   | 
|  1|PENELOPE |GUINESS  |2/15/2006 4:34:33 AM| 
|  2|NICK  |WAHLBERG |2/15/2006 4:34:33 AM| 
|  3|ED  |CHASE  |2/15/2006 4:34:33 AM| 
|  4|JENNIFER |DAVIS  |2/15/2006 4:34:33 AM| 
|  5|JOHNNY |LOLLOBRIGIDA|2/15/2006 4:34:33 AM| 
---------------------------------------------------------------- 

在ADO(經典,與2.8版測試)的數據庫,你 可以節省使用

oRS.Save sFSpec, adPersistXML 

結果集到XML這就給了你XML如:

<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882' 
    xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882' 
    xmlns:rs='urn:schemas-microsoft-com:rowset' 
    xmlns:z='#RowsetSchema'> 
<s:Schema id='RowsetSchema'> 
    <s:ElementType name='row' content='eltOnly'> 
     <s:AttributeType name='actor_id' rs:number='1' rs:nullable='true' rs:maydefer='true' rs:writeunknown='true'> 
      <s:datatype dt:type='i2' dt:maxLength='2' rs:precision='5' rs:fixedlength='true'/> 
     </s:AttributeType> 
     <s:AttributeType name='first_name' rs:number='2' rs:nullable='true' rs:maydefer='true' rs:writeunknown='true'> 
      <s:datatype dt:type='string' dt:maxLength='45'/> 
     </s:AttributeType> 
     <s:AttributeType name='last_name' rs:number='3' rs:nullable='true' rs:maydefer='true' rs:writeunknown='true'> 
      <s:datatype dt:type='string' dt:maxLength='45'/> 
     </s:AttributeType> 
     <s:AttributeType name='last_update' rs:number='4' rs:nullable='true' rs:maydefer='true' rs:writeunknown='true'> 
      <s:datatype dt:type='dateTime' rs:dbtype='variantdate' dt:maxLength='16' rs:fixedlength='true'/> 
     </s:AttributeType> 
     <s:extends type='rs:rowbase'/> 
    </s:ElementType> 
</s:Schema> 
<rs:data> 
    <z:row actor_id='1' first_name='PENELOPE' last_name='GUINESS' last_update='2006-02-15T04:34:33'/> 
    <z:row actor_id='2' first_name='NICK' last_name='WAHLBERG' last_update='2006-02-15T04:34:33'/> 
    <z:row actor_id='3' first_name='ED' last_name='CHASE' last_update='2006-02-15T04:34:33'/> 
    <z:row actor_id='4' first_name='JENNIFER' last_name='DAVIS' last_update='2006-02-15T04:34:33'/> 
    <z:row actor_id='5' first_name='JOHNNY' last_name='LOLLOBRIGIDA' last_update='2006-02-15T04:34:33'/> 
</rs:data> 
</xml> 

要讀取該數據,從(本地,控制檯)代碼開始,如:

Dim oFS : Set oFS = CreateObject("Scripting.FileSystemObject") 
    Dim sDDir : sDDir  = oFS.GetAbsolutePathName("..\Data") 
    Dim sFSpec : sFSpec = oFS.GetAbsolutePathName("..\Data\actor.xml") 
    Dim oXDoc : Set oXDoc = CreateObject("msxml2.domdocument") 
    Dim sXPath, ndFnd, ndlFnd, attrX, nIdx 
    oXDoc.async    = False 
    oXDoc.validateOnParse = False 
    oXDoc.resolveExternals = False 
    oXDoc.setProperty "SelectionLanguage", "XPath" 
    oXDoc.setProperty "SelectionNamespaces", Join(Array(_ 
     "xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'" _ 
    , "xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'" _ 
    , "xmlns:rs='urn:schemas-microsoft-com:rowset'" _ 
    , "xmlns:z='#RowsetSchema'" _ 
), " ") 
    If oXDoc.load(sFSpec) Then 
    WScript.Echo sFSpec, "looks good." 
    For Each sXPath In Array(_ 
       "/xml" _ 
      , "/xml/s:Schema" _ 
      , "/xml/rs:data" _ 
      , "/xml/rs:data/z:row[@actor_id=""2""]" _ 
     ) 
     WScript.Stdout.Write "|" & sXPath & "| => " 
     Set ndFnd = oXDoc.selectSingleNode(sXPath) 
     If ndFnd Is Nothing Then 
      WScript.Stdout.WriteLine "not found" 
     Else 
      WScript.Stdout.WriteLine "found a(n) " & ndFnd.tagName 
     End If 
    Next 
    WScript.Echo "-----------------------" 

'<rs:data> 
' <z:row actor_id='1' first_name='PENELOPE' last_name='GUINESS' last_update='2006-02-15T04:34:33'/> 
'  ... 
'</rs:data> 
    sXPath = "/xml/rs:data/z:row[@actor_id=""3""]" 
    Set ndFnd = oXDoc.selectSingleNode(sXPath) 
    If ndFnd Is Nothing Then 
     WScript.Echo "|", sXPath, "| not found" 
    Else 
     For Each attrX In ndFnd.Attributes 
      WScript.Echo attrX.Name, attrX.Value 
     Next 
    End If 
    WScript.Echo "-----------------------" 

    sXPath = "/xml/rs:data/z:row" 
    Set ndlFnd = oXDoc.selectNodes(sXPath) 
    If ndlFnd Is Nothing Then 
     WScript.Echo "ndlFnd Is Nothing" 
    Else 
     If 0 = ndlFnd.Length Then 
      WScript.Echo "ndlFnd is empty" 
     Else 
      For Each ndFnd In ndlFnd 
       WScript.Echo TypeName(ndFnd) 
       For Each attrX In ndFnd.Attributes 
        WScript.Echo "", attrX.Name, attrX.Value 
       Next 
      Next 
     End If 
    End If 
    Else 
    WScript.Echo "Bingo!" 
    WScript.Echo oXDoc.parseError.reason 
    End If 

的重要步驟:

  • 對於開發/測試避免使用服務器的額外的複雜性; 如果CSCRIPT readxml.vbs成功,很容易「端口」的工作代碼 爲.asp(和處理單獨服務器的具體問題)
  • 創建msxml2.domdocument
  • ,將其配置;特別是從命名空間的XML標記複製到 SelectionNamespaces
  • 加載該文件,檢查錯誤
  • 指定XPath表達式(小心!嘗試從樣品到XPATH「翻譯」 XML)
  • 檢查).selectSingleNode的結果()和.selectNodes(
  • 訪問保存數據
+0

我在頂部添加了遠程代碼而不是靜態內容,修改它以找到我想要的和結果Bingo !.非常感謝你。 – HAWood 2012-01-27 15:51:25

1

讓我們假設你貼的XML)包括正確的命名空間別名和b),它已經在XML_response正確加載的屬性。

現在,「正確」的方法是使用XPath,但是在這種情況下,我們可以用更簡單的代碼實現我們的目標。 MSXML(3或更低版本)中的默認選擇語言是XSL模式,該選擇不理解命名空間別名,所以<rs:data>從其角度來看具有標記名稱「rs:data」而不是「data」。這就是你做錯的第一件事。

另一件事是getElementsByTag返回一個節點的集合,它只包含一個節點「rs:data」。您的代碼試圖從該節點讀取「field」屬性,實際上它位於「z:row」的子節點上。

這裏是你的代碼應該是什麼樣子:

Dim objData: Set objData = XML_response.documentElement.selectSingleNode("rs:data") 

Dim row 
Dim fieldVal, field1Val 
For Each row in objData.selectNodes("z:row") 
    fieldVal = row.getAttribute("field") 
    field1Val = row.getAttribute("field1") 

    ''# Do stuff with your fields for each row found. 
Next 
+0

這正是我的原始方法,但事實證明它不是方法,而是xml返回的方式。該文檔沒有聲明它,但行集xml被另一個xml文檔包裝,這意味着我必須先將我們的內部xml拉到最後,然後才能工作。我之前沒有發現這個的原因是因爲當我使用loadXML時,它解析它就好了,只返回內部xml,即使它實際上是錯誤的而沒有引發錯誤。一個非常非常奇怪的發生,但它的工作謝謝你們的幫助。 – HAWood 2012-01-30 12:47:31