从 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
我用 selectNodes
和 selectSingleNode
做了一些尝试,它们只显示客户名称或支票描述。我还没有设法得到这些值。
像这样使用 selectNodes
和 selectSingleNode
:
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
我有一个包含大量数据的 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
我用 selectNodes
和 selectSingleNode
做了一些尝试,它们只显示客户名称或支票描述。我还没有设法得到这些值。
像这样使用 selectNodes
和 selectSingleNode
:
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