从具有特定值的 Parent 下的 XML 文件中获取子节点的数量

Get the count of child nodes from XML file under a Parent having a specific value

我有一个示例 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>

如果 ParentLevel4additional 的值为 "My Data Matches",我需要节点 ParentLevel4 下的节点数 <MyNode>

我尝试了以下脚本,但无法找到解决方案:

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

你的代码有几个错误:

  1. 删除 XPath 末尾多余的 /,因为它会给您错误的结果。
  2. 下一行中的 XPath 缺少级别 (ParentLevel3):

    Set ObjMyNodes=xmlDoc.selectNodes ("//ParentLevel1/ParentLevel2/ParentLevel4/MyNode/")
    
  3. 即使您将缺少的级别添加到上面的行中,它仍然会计算所有 MyNode 节点,因为您要重新 selecting 来自的节点开始。此外,如果您有多个匹配项,它将计算所有 MyNode 节点乘以匹配项的数量,因此您将得到不需要的 + 重复结果。

你走在正确的轨道上,但你应该只 select 匹配节点的兄弟节点。像下面这样的东西应该会给你你需要的结果:

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 Codes042018_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