从 XML 获取多个值(经典 ASP)

Get multiple values from XML (Classic ASP)

我有一个包含大量数据的 XML 文件,我想获取一些值以在经典 ASP.

中进一步处理

我的 XML 文件如下所示;

<result>
<items>
    <client>
        <clientid>12345</clientid>
        <name>Acme Inc</name>
        <site>
            <siteid>98765</siteid>
            <name>Acme Site</name>
            <workstations>
                <workstation>
                    <id>12345</id>
                    <name>LAPTOP1</name>
                    <failed_checks>
                        <check>
                            <checkid>9876543</checkid>
                            <check_type>687</check_type>
                            <description>Smart Error</description>
                            <startdate>2015-04-09</startdate>
                            <starttime>12:01:00</starttime>
                            <formatted_output>Smart Error</formatted_output>
                        </check>
                    </failed_checks>
                </workstation>
            </workstations>
        </site>
    </client>
    <client>
        <clientid>67543</clientid>
        <name>Contoso Ltd</name>
        <site>
            <siteid>98732</siteid>
            <name>Contoso Site A</name>
            <servers>
                <server>
                    <id>789999</id>
                    <name>SERVER1</name>
                    <failed_checks>
                        <check>
                            <checkid>76543555</checkid>
                            <check_type>2918</check_type>
                            <description>Disk Space Error - C:</description>
                            <startdate>2015-04-09</startdate>
                            <starttime>12:01:00</starttime>
                            <formatted_output>Total: 136.70GB, Free: 0.57GB</formatted_output>
                        </check>
                    </failed_checks>
                </server>
            </servers>
        </site>
    </client>       
</items>

我所有的尝试都没有完全满足我的需求。 每个 <client> 获得一个值没有问题。我可以检索 <client><name> 或者我可以毫无困难地获得 <check><description> 的值。我的问题是当我想要 <client><name><workstation><name><server><name> 以及 <check><description><check><startdate>.

的值时

所以换句话说,我想得到这个输出; Acme Inc LAPTOP1 智能错误 2015-04-09 Contoso Ltd SERVER1 磁盘 Space 错误 - C: 2015-04-09

我得到的最好结果是使用这段代码; (它可以工作,但显示不正确 - <check><description><client><name> 不匹配) 所以我的输出现在更像这样; Acme Inc SERVER1 磁盘 Space 错误 - C: 2015-04-09 Contoso Ltd LAPTOP1 智能错误 2015-04-09

Set xmlDOM = Server.CreateObject("MSXML2.DOMDocument")
xmlDOM.async = False
xmlDOM.setProperty "ServerHTTPRequest", True
xmlDOM.Load("my xml file")

Set Root = xmlDOM.documentElement
Set NodeList = Root.getElementsByTagName("client")

For i = 0 to NodeList.length -1
  Set clientid = xmlDOM.getElementsByTagName("clientid")(i)
  Set name = xmlDOM.getElementsByTagName("name")(i)
  Set ckdesc = xmlDOM.getElementsByTagName("site/*/*/failed_checks/check/description")(i)
  Set ckdev = xmlDOM.getElementsByTagName("site/*/*/name")(i) 

  Response.Write clientid.text & " " & name.text & " " & ckdev.text & " " & ckdesc.text & "<br>"
Next

Set xmlDOM = Nothing
Set NodeList = Nothing

我用 selectNodesselectSingleNode 做了一些尝试,它们只显示客户名称或支票描述。我还没有设法得到这些值。

像这样使用 selectNodesselectSingleNode

Dim xmlDOM
Set xmlDOM = Server.CreateObject("MSXML2.DOMDocument")
xmlDOM.LoadXml(sXml)

Dim NodeList, i, clientid, name, ckdesc, ckdev

Set NodeList = xmlDom.selectNodes("/result/items/client")

For i = 0 to NodeList.length -1
  Set clientid = NodeList(i).selectSingleNode("./clientid")
  Set name = NodeList(i).selectSingleNode("./name")
  Set ckdesc = NodeList(i).selectSingleNode("./site/*/*/failed_checks/check/description")
  Set ckdev = NodeList(i).selectSingleNode("./site/*/*/name")

  Response.Write clientid.text & " " & name.text & " " & ckdev.text & " " & ckdesc.text & "<br>"
Next

Set xmlDOM = Nothing
Set NodeList = Nothing

这段代码并不理想,因为在获取 属性 值之前 clientid.text 和其他你需要检查对象是否存在(不是什么都没有),以及更多的错误检查。

我正在添加一个 VMV 答案的答案,以便能够更轻松地显示我的代码和输出。

VMV,您建议的代码非常有效!在看到您的工作代码的输出之前,我没有看到整件事。 现在的问题是每个 <client> 可以有多个 <sites> 并且每个 <site> 可以有多个 <workstations><servers> 当然还有多个 <check>.

如何在每个 (i) 中做一个循环?

我试过像下面的代码那样做: 设置节点列表 = xmlDom.selectNodes("/result/items/client")

For i = 0 to NodeList.length -1
  Set clientid = NodeList(i).selectSingleNode("./clientid")
  Set name = NodeList(i).selectSingleNode("./name")

    Set NodeList2 = xmlDom.selectNodes("/result/items/client/site/*/*")
    For j = 0 to NodeList2.length -1
    Set ckdev = NodeList2(j).selectSingleNode("./name")     
        If Not ckdev Is Nothing Then    
            strckdev = strckdev & ckdev.text & " "
        Else
            strckdev = strckdev & "<br>"
        End If              

            Set NodeList3 = xmlDom.selectNodes("/result/items/client/site/*/*/failed_checks/check")
            For k = 0 to NodeList3.length -1
            Set ckdesc = NodeList3(k).selectSingleNode("./description")
              If Not ckdesc Is Nothing Then
                strckdesc = strckdesc & ckdesc.text & "<br>"
              Else
                strckdesc = strckdesc & "<br>"
              End If 
            Next      
    Next   

Response.Write clientid.text & " " & name.text & " " & strckdev & " " & strckdesc & "<br>"
Next

现在我得到每个 <clientid> 每个 <site>。不只是那个特定的 <site> <clientid> (i).

结果是这样的:

12345 Acme Inc LAPTOP1 SERVER1 Smart Error Disk Space Error - C:   
67543 Contoso Ltd LAPTOP1 SERVER1 Smart Error Disk Space Error - C:  

我更想寻找这个结果(如果单台或多台计算机出现单个或多个错误):

12345 Acme Inc 
      LAPTOP1 Smart Error 
      LAPTOP3 Some other error 
              Second error 

67543 Contoso Ltd
      SERVER1 Disk Space Error - C:
      Server7 Some other error

所以我的问题是,我如何在循环中循环..?

我的代码中有一些明显的错误,我设置 NodeList2 和 Set NodeList3 再次通过 XML 文件,这就是我输出错误的原因。

我也试过这样做(基于 VMVs 代码);

Set clientid = NodeList(i).selectSingleNode("./clientid")
Set name = NodeList(i).selectSingleNode("./name")
Set ckdev = NodeList(i).selectNodes("./site/*/*/name") 
 For Each device In ckdev
   If Not device Is Nothing Then    
    strckdev = strckdev & device & " "
   Else
    strckdev = strckdev & "<br>"
   End If 
 Next

Slint,我不能做你所有的工作,抱歉,但我认为这个算法可以帮助你解决问题:

Dim nodeListClient, nodeClient
Dim nodeListSite, nodeSite
Dim nodeListMachine, nodeMachine

' getting multiply <client> nodes
Set nodeListClient = xmlDom.selectNodes("/result/items/client")

' looping through collection
For Each nodeClient In nodeListClient

    ' getting multiply <site> nodes
    Set nodeListSite = nodeClient.selectNodes("./site")

    ' looping through collection    
    For Each nodeSite In nodeListSites

        ' getting multiply <workstation> or <server> nodes
        Set nodeListMachine = nodeSite.selectNodes("./*/*")

        ' looping through collection
        For Each nodeMachine In nodeListMachine
            ' there you will working with nodeMachine object
            ' nodeMachine contains <id>, <name> and other nodes
        Next
    Next

Next

我建议您学习 XPath 文档和示例,例如https://msdn.microsoft.com/en-us/library/ms256115(v=vs.110).aspx

基于 VMV 的回答,这是我的工作代码。数据以原始文本输出,没有很好的呈现。

Set xmlDOM = Server.CreateObject("MSXML2.DOMDocument")
xmlDOM.async = False
xmlDOM.setProperty "ServerHTTPRequest", True
xmlDOM.Load("XMLfiletoload")

Dim nodeListClient, nodeClient
Dim nodeListSite, nodeSite
Dim nodeListMachine, nodeMachine
Dim nodeError, nodeErrorList

' getting multiply <client> nodes
Set nodeListClient = xmlDom.selectNodes("/result/items/client")

' looping through collection
For Each nodeClient In nodeListClient
  Set clientid = nodeClient.selectSingleNode("./clientid")
  Set name = nodeClient.selectSingleNode("./name")
    ' getting multiply <site> nodes
  strCLIENT = clientid.text & " " & name.text & "<br>"

    Set nodeListSite = nodeClient.selectNodes("./site")

    ' looping through collection    
    For Each nodeSite In nodeListSite
        Set cksite = nodeSite.selectSingleNode("./name")
        If Not cksite Is Nothing Then 
            strSITE = cksite.text & " "
        Else
            strSITE = " "
        End If

        ' getting multiply <workstation> or <server> nodes
        Set nodeListMachine = nodeSite.selectNodes("./*/*")

        ' looping through collection
        For Each nodeMachine In nodeListMachine
            ' there you will working with nodeMachine object
            ' nodeMachine contains <id>, <name> and other nodes

            Set ckdev = nodeMachine.selectSingleNode("./name")
            If Not ckdev Is Nothing Then 
                strONEDEVICE = ckdev.text & " "
            Else
                strONEDEVICE = ""
            End If  

            Set nodeErrorList = nodeMachine.selectNodes("./failed_checks/check")            
            ' looping through collection
            For Each nodeError In nodeErrorList
                    ' there you will working with nodeError object
                    ' nodeError contains <id>, <name> and other nodes

                Set ckdesc = nodeError.selectSingleNode("./description")
                If Not ckdesc Is Nothing Then 
                    strERROR = strERROR & ckdesc.text & "<br>"
                Else
                    strERROR = strERROR & "<br>"
                End If  

            Next
        strDEVICE = strDEVICE & strONEDEVICE & strERROR
        Next
        strSITE = strSITE & strDEVICE
    Next
              Response.Write strCLIENT & " " & strSITE & "<br>"
              strCLIENT = ""
              strSITE = ""
              strONEDEVICE = ""
              strDEVICE = ""
              strERROR = ""

Next