Как перебрать дочерние узлы узла после его выбора с помощью selectSingleNode - PullRequest
0 голосов
/ 04 января 2019

Я пытаюсь выбрать один узел из XML-документа с помощью selectSingleNode(), а затем использовать selectNodes на этом узле для дальнейшего выбора дочерних элементов этого узла:

option explicit

sub main() ' {

   dim doc as new MSXML2.DOMDocument

   doc.loadXML(                                                                                     _
     "<items>"                                                                                    & _
     "  <item id='1000'><name val='ABC'/><name val='DEF'/><name val='GHI'/><foo>xxx</foo></item>" & _
     "  <item id='1001'><name val='JKL'/><name val='MNO'/><name val='PQR'/><bar>yyy</bar></item>" & _
     "  <item id='1002'><name val='STU'/><name val='VWX'/><name val='YZ.'/><baz>zzz</baz></item>" & _
     "</items>")

    dim item as msxml2.IXMLDOMElement
    set item = doc.selectSingleNode("//item[@id='1002']")

    dim names as msxml2.IXMLDOMSelection
    set names = item.selectNodes("//name")

    dim name as msxml2.IXMLDOMElement
    for each name in names
        debug.print(name.getAttribute("val"))
    next name

end sub ' }

Я ожидал этогокусок кода для печати значений атрибутов STU, VWX и YZ..Однако при запуске он печатает каждое значение <name> val.

Очевидно, selectNodes() выбирает все узлы из корневого документа.

Я не понимаю, почемуэто и как я могу получить реальные дочерние узлы ранее выбранного узла.

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Изменение

Set names = item.selectNodes("//name")

К

Set names = item.SelectNodes("name")
0 голосов
/ 04 января 2019

Вы хотите перебрать выборку, возвращаемую xpath, показанным ниже.По сути, это набор узлов, содержащий узлы атрибутов.

Option Explicit
Public Sub main()
   Dim doc As New MSXML2.DOMDocument60

   doc.LoadXML ( _
     "<items>" & _
     "  <item id='1000'><name val='ABC'/><name val='DEF'/><name val='GHI'/><foo>xxx</foo></item>" & _
     "  <item id='1001'><name val='JKL'/><name val='MNO'/><name val='PQR'/><bar>yyy</bar></item>" & _
     "  <item id='1002'><name val='STU'/><name val='VWX'/><name val='YZ.'/><baz>zzz</baz></item>" & _
     "</items>")

    Dim items As IXMLDOMSelection, item As Object
    Set items = doc.SelectNodes("//*[@id='1002']/name/@*") 'all attribs. Or, //*[@id='1002']/name/@val for only val attributes
    For Each item In items
        Debug.Print item.text
    Next
End Sub

Если вы хотите более подробный метод

Option Explicit
Public Sub main()
    Dim doc As New MSXML2.DOMDocument60

    doc.LoadXML ( _
                "<items>" & _
                "  <item id='1000'><name val='ABC'/><name val='DEF'/><name val='GHI'/><foo>xxx</foo></item>" & _
                "  <item id='1001'><name val='JKL'/><name val='MNO'/><name val='PQR'/><bar>yyy</bar></item>" & _
                "  <item id='1002'><name val='STU'/><name val='VWX'/><name val='YZ.'/><baz>zzz</baz></item>" & _
                "</items>")

    Dim item As Object, attrib As Object, child As Object
    Set item = doc.SelectSingleNode("//*[@id='1002']")

    For Each child In item.ChildNodes
        For Each attrib In child.Attributes
            If attrib.name = "val" Then Debug.Print attrib.name, attrib.text
        Next
    Next
End Sub

Вы можете даже возиться с:

For Each child In item.ChildNodes
    If child.BaseName = "name" And child.getAttribute("val") <> vbNullString Then Debug.Print child.getAttribute("val")
Next
...