Получить количество дочерних узлов из XML-файла для Parent, имеющего конкретное значение
У меня есть образец XML-файла, который построен следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<ParentLevel1>
<ParentLevel2>
<ParentLevel3>
<ParentLevel4>
<MyNode>Data 1</MyNode>
<MyNode>Data 2</MyNode>
<MyNode>Data 3</MyNode>
<MyNode>Data 4</MyNode>
<MyNode>Data 5</MyNode>
<MyNode>Data 6</MyNode>
</ParentLevel4>
<ParentLevel4additional>My Data Matches</ParentLevel4additional>
</ParentLevel3>
<ParentLevel3>
<ParentLevel4>
<MyNode>Data 7</MyNode>
<MyNode>Data 8</MyNode>
<MyNode>Data 9</MyNode>
<MyNode>Data 10</MyNode>
<MyNode>Data 11</MyNode>
<MyNode>Data 12</MyNode>
</ParentLevel4>
<ParentLevel4additional>My Data does not Match</ParentLevel4additional>
</ParentLevel3>
</ParentLevel2>
</ParentLevel1>
Мне нужно количество узлов <MyNode>
под узлом ParentLevel4
если значение ParentLevel4additional
это "Мои данные".
Я попытался с помощью приведенного ниже сценария, и я не мог получить решение:
MyNodeCount = 0
AdditionNodeCount = 0
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.Async = "False"
If (xmlDoc.Load(strXMLFile)) Then
Set AdditionNode =xmlDoc.selectNodes ("//ParentLevel1/ParentLevel2/ParentLevel3/ParentLevel4additional/")
For Each ParentLevel4additional in AdditionNode
if ParentLevel4additional.Text = "My Data Matches" Then
Set ObjMyNodes=xmlDoc.selectNodes ("//ParentLevel1/ParentLevel2/ParentLevel4/MyNode/")
For Each MyNode in ObjMyNodes
MyNodeCount = MyNodeCount + 1
Next
AdditionNodeCount = AdditionNodeCount + 1
End If
Next
Wscript.Echo MyNodeCount
Wscript.Echo AdditionNodeCount
Else
WScript.Echo "Error loading XML file '" & strXMLFile & "'." & vbCrLf & _
"Error code: 0x" & Hex(xmlDoc.ParseError.ErrorCode) & vbCrLf & _
"Description: " & xmlDoc.ParseError.Reason & vbCrLf & _
"Line: " & xmlDoc.ParseError.Line & vbCrLf & _
"Character: " & xmlDoc.ParseError.LinePos
WScript.Quit 1
End If
2 ответа
В вашем коде есть несколько ошибок:
- Удалить лишний
/
в конце вашего XPath, потому что он даст вам ложные результаты. В XPath в следующей строке отсутствует уровень (
ParentLevel3
):Set ObjMyNodes=xmlDoc.selectNodes ("//ParentLevel1/ParentLevel2/ParentLevel4/MyNode/")
Даже если вы добавите недостающий уровень в строку выше, он все равно будет считать все
MyNode
узлы, потому что вы повторно выбираете узлы с самого начала. Более того, если у вас есть более одного совпадения, он будет считать всеMyNode
узлы умножаются на количество совпадений, так что вы получите нежелательные + дублированные результаты.
Вы находитесь на правильном пути, но вы должны только выбрать узлы, которые являются родственными для соответствующего узла. Что-то вроде следующего должно дать вам нужный результат:
If (xmlDoc.Load(strXMLFile)) Then
Set NodesList = xmlDoc.SelectNodes("//ParentLevel1/ParentLevel2/ParentLevel3")
For Each node in NodesList
Set ParentLevel4additional = node.SelectSingleNode("ParentLevel4additional")
If ParentLevel4additional.Text = "My Data Matches" Then
For Each myNode in node.SelectNodes("ParentLevel4/MyNode")
MyNodeCount = MyNodeCount + 1
Next
AdditionNodeCount = AdditionNodeCount + 1
End If
Next
Wscript.Echo MyNodeCount
Wscript.Echo AdditionNodeCount
Else
WScript.Echo "Error loading XML file '" & strXMLFile & "'." & vbCrLf & _
"Error code: 0x" & Hex(xmlDoc.ParseError.ErrorCode) & vbCrLf & _
"Description: " & xmlDoc.ParseError.Reason & vbCrLf & _
"Line: " & xmlDoc.ParseError.Line & vbCrLf & _
"Character: " & xmlDoc.ParseError.LinePos
WScript.Quit 1
End If
Используйте xPath:
//ParentLevel3[ParentLevel4additional='My Data Matches']/ParentLevel4
Вы можете использовать следующий код, чтобы получить количество дочерних узлов нужного родительского узла:
Dim xmlPath, objXml, xPath
xmlPath = "J:\Documents\Gurman\Work\PersonalWork\Misc Codes\26042018_SO\source.xml"
set objXml = CreateObject("Microsoft.Xmldom")
objXml.async = False
objXml.load xmlPath
xPath = "//ParentLevel3[ParentLevel4additional='My Data Matches']/ParentLevel4"
set objNode = objXml.selectSingleNode(xPath)
set childnodes = objNode.ChildNodes
i=0
for each node in childnodes
i = i+1
next
msgbox "No. of ChildNodes = " & i
set objNode = Nothing
set objXml = Nothing