Получить количество дочерних узлов из XML-файла для Parent, имеющего конкретное значение - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть образец 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 ]

0 голосов
/ 26 апреля 2018

Использовать 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
0 голосов
/ 26 апреля 2018

В вашем коде есть несколько ошибок:

  1. Удалите лишние / в конце вашего XPath, потому что это даст вам ложные результаты.
  2. В XPath в следующей строке отсутствует уровень (ParentLevel3):

    Set ObjMyNodes=xmlDoc.selectNodes ("//ParentLevel1/ParentLevel2/ParentLevel4/MyNode/")
    
  3. Даже если вы добавите отсутствующий уровень в строку выше, он все равно будет считать все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
...