使用selectSingleNode选择节点后如何遍历节点的子节点

时间:2019-01-04 09:45:37

标签: xml vba msxml

我正在尝试使用selectSingleNode()从XML文档中选择一个节点,然后在该节点上使用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 ' }

我期望这段代码可以打印属性值STUVWXYZ.。但是,在运行它时,它将打印每个<name>的{​​{1}}值。

显然,val从根文档中选择所有节点。

我不明白为什么会这样,以及如何获取先前选择的节点的 real 子节点。

2 个答案:

答案 0 :(得分:1)

更改

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

收件人

Set names = item.SelectNodes("name")

答案 1 :(得分:0)

您要遍历如下所示的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