我有一个包含大量数据的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磁盘空间错误 - C:2015-04-09
我得到的最好结果是使用此代码; (它正常工作,但显示不正确 - <check><description>
与<client><name>
不匹配)
所以我的输出现在更像这样;
Acme Inc SERVER1磁盘空间错误 - 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
进行了一些尝试,只显示客户端名称或检查说明。我没有设法得到价值观。
答案 0 :(得分:1)
像这样使用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
之前,您需要检查该对象是否存在(并非一无所获),以及更多错误检查。
答案 1 :(得分:1)
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
答案 2 :(得分:0)
我正在为VMV答案添加答案,以便能够更轻松地显示我的代码和输出。
VMV,您建议的代码就像一个魅力!直到我看到你工作代码的输出,我才看到整件事。
现在的问题是每个<client>
可以有多个<sites>
,每个<site>
可以有多个<workstations>
或<servers>
,当然还有多个<check>
。< / p>
如何在每个(i)
进行循环?
我尝试过以下代码: 设置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 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
我更喜欢这个结果(如果单个或多个计算机出现单个或多个错误):
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
所以我的问题是,我如何在循环中循环..?
在我的代码中有明显的错误,我设置NodeList2和Set NodeList3,因为它再次通过XML文件,这就是我输出错误的原因。
我也尝试过这样做(基于VMV代码);
{{1}}
答案 3 :(得分:0)
根据VMVs答案,这是我的工作代码。原始文本中的数据输出没有很好的演示文稿。
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