По какой-то причине я не могу заставить это работать. У меня есть следующий XML с 2 узлами регистрации. Все, что мне нужно, это вернуть <serialnumber> (что в настоящее время делает скрипт) как значение переменной и все <id>, <qty> для этого <serialnumber>.

Я могу добраться до "серийного номера" (см. Код ниже), но не могу получить цикл для отдельного <module>, работающего, чтобы получить все <id>, <qty>. Я получаю Объект не поддерживает это свойство или метод: ответ 'ModuleList.length' .

===================== 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
0
Milan 15 Май 2014 в 22:36

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
2
Ekkehard.Horner 15 Май 2014 в 20:21

Почему бы вам не использовать для этого регулярное выражение?

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
-1
nowox 15 Май 2014 в 19:56