2014-05-15 108 views
0

出于某种原因,我无法完成这项工作。我有以下2个注册节点的XML。我需要的只是返回一个<serialnumber>(脚本当前所做的)作为变量值,并且此<serialnumber>的所有<id>, <qty>用VB脚本解析XML

我可以尽量得到的“序列号”(见下面的代码),但似乎无法得到循环对个人<module>为了得到所有<id>, <qty>工作。我收到对象不支持此属性或方法:'ModuleList.length' response。

===================== XML ========= =======

<root> 
<registration> 
    <name>For Test</name> 
    <serialnumber>1234567890</serialnumber> 
    <modules> 
     <module> 
      <name>SERVER : A</name> 
      <id>15</id> 
      <qty>1</qty> 
     </module> 
     <module> 
      <name>SERVER : B</name> 
      <id>40</id> 
      <qty>1</qty> 
     </module> 
    </modules> 
</registration> 
<registration> 
    <name>For Test</name> 
    <serialnumber>0987654321</serialnumber> 
    <modules> 
     <module> 
      <name>SERVER : 1</name> 
      <id>15</id> 
      <qty>1</qty> 
     </module> 
     <module> 
      <name>SERVER : 2</name> 
      <id>40</id> 
      <qty>1</qty> 
     </module> 
     <module> 
      <name>SERVER : 3</name> 
      <id>15</id> 
      <qty>1</qty> 
     </module> 
     <module> 
      <name>SERVER : 4</name> 
      <id>40</id> 
      <qty>1</qty> 
     </module> 
    </modules> 
</registration> 
</root> 

===================== VB脚本============= ===

Set objXML = Server.CreateObject("Msxml2.DOMDocument") 

objXML.LoadXml(xmlString) 

Set Root = objXML.documentElement 
Set registrationList = Root.getElementsByTagName("registration") 

For i = 0 to registrationList.length -1 

    Set serialnumber = objXML.getElementsByTagName("serialnumber")(i) 

    Set ModuleList = Root.getElementsByTagName("modules")(i) 

    For x = 0 to ModuleList.length -1 

     Set module = objXML.getElementsByTagName("module")(x) 

     Response.Write module.text ' this is where I was expecting to stuff the array 


    Next 


    Response.Write serialnumber.text & " " 

Next 

Set objXML = Nothing 

回答

2

XML是结构化数据,所以使用结构化方法(XPath)来处理它。重复/嵌套getElementsByTagName()松散的层次关系。在代码:

Dim oFS  : Set oFS  = CreateObject("Scripting.FileSystemObject") 
    Dim sFSpec : sFSpec  = goFS.GetAbsolutePathName("..\testdata\xml\so23686152.xml") 
    Dim objMSXML : Set objMSXML = CreateObject("Msxml2.DOMDocument") 
    objMSXML.setProperty "SelectionLanguage", "XPath" 
    objMSXML.async = False 
    objMSXML.load sFSpec 

    If 0 = objMSXML.parseError Then 
    Dim ndlReg : Set ndlReg = objMSXML.selectNodes("/root/registration") 
    Dim ndReg 
    For Each ndReg In ndlReg 
     WScript.Echo ndReg.selectSingleNode("serialnumber").text 
     Dim ndMod 
     For Each ndMod In ndReg.selectNodes("modules/module") 
      WScript.Echo " " _ 
          , ndMod.firstChild.text _ 
          , ndMod.selectSingleNode("id").text _ 
          , ndMod.childNodes(2).text 
     Next 
    Next 
    Else 
    WScript.Echo objMSXML.parseError.reason 
    End If 

输出:

1234567890 
    SERVER : A 15 1 
    SERVER : B 40 1 
0987654321 
    SERVER : 1 15 1 
    SERVER : 2 40 1 
    SERVER : 3 15 1 
    SERVER : 4 40 1 
-1

为什么你不使用正则表达式呢?

Const ForReading = 1 
Set objFSO = CreateObject("Scripting.FileSystemObject") 
Set objFile = objFSO.OpenTextFile("test.xml", ForReading) 

text = objFile.ReadAll 

Dim serialNumber 
Set objRE = New RegExp 
objRE.pattern = "<serialnumber>([0-9]+)</serialnumber>" 
Set matches = objRE.execute(text) 
if matches.count > 0 then 
    serialNumber = matches.item(0).submatches.item(0) 
end if 
+0

因为它的XML,而不是文字。 (-1) –