VBA XML解析 - 循环子节点

时间:2016-11-17 15:20:10

标签: xml excel vba

这是我第一次尝试使用VBA解析XML文件,所以我可能会忽略这一点; 我已经可以打印出来了:

<values>
    <value code="1">A</value>
    <value code="2">B</value>
    <value code="3">C</value>
</values>

使用此代码行:

Debug.Print Variable.SelectSingleNode("values").XML

,其中values是其父Variable

的子节点

但我无法弄清楚是如何在values的孩子中徘徊,并打印&#34; 1A&#34;,&#34; 2B&#34; ,&#34; 3C&#34;对

据我所知,this question使用了根的第一个孩子,而我的目标是深入了解多层次的结构。

2 个答案:

答案 0 :(得分:3)

在这里,我们可以看到如何使用MSXML6.0库为您的特定示例解析XML。要使用此示例,您需要在VBA项目中添加对MSXML6.0的引用。

我建议你特别注意XPath变量&#39; // value&#39;和选择器,例如.getNamedItem(&#34; code&#34;)---为了熟练使用XML解析,你需要熟悉其中的许多内容。幸运的是,这很多都转移到HTML解析中,所以它是一项有用的技能!

在这种情况下,我选择了所有值节点。迭代它们就像根据节点数组的长度和使用.item(i)调用进行for循环一样简单。

Option Explicit
Sub test()
    Dim strXml As String
    strXml = "<values><value code=""1"">A</value><value code=""2"">B</value><value code=""3"">C</value></values>"

    Dim objXML As MSXML2.DOMDocument60
    Set objXML = New MSXML2.DOMDocument60

    If Not objXML.LoadXML(strXml) Then  'strXML is the string with XML'
        Err.Raise objXML.parseError.ErrorCode, , objXML.parseError.reason
    End If

    Dim entry_point As IXMLDOMNode
    Set entry_point = objXML

    Dim myNodes As IXMLDOMNodeList
    Dim myElement As IXMLDOMElement
    Dim myNode As IXMLDOMNode
    Dim nNode As Integer
    Set myNodes = entry_point.SelectNodes("//value")
    If myNodes.Length > 0 Then
        For nNode = 0 To myNodes.Length
            Set myNode = myNodes(nNode) ' Get the first node.
            If myNode Is Nothing Then
            Else
                Debug.Print myNode.Text
                Debug.Print myNode.Attributes.getNamedItem("code").Text
            End If
        Next nNode
    Else
        Debug.Print "No nodes found."
    End If

End Sub

这是另一种情况,我选择所有VALUES节点,然后遍历每个VALUES节点的子节点(假设所有值节点只有值子节点)。

Option Explicit
Sub test()
    Dim strXml As String
    strXml = "<values><value code=""1"">A</value><value code=""2"">B</value><value code=""3"">C</value></values>"

    Dim objXML As MSXML2.DOMDocument60
    Set objXML = New MSXML2.DOMDocument60

    If Not objXML.LoadXML(strXml) Then  'strXML is the string with XML'
        Err.Raise objXML.parseError.ErrorCode, , objXML.parseError.reason
    End If

    Dim entry_point As IXMLDOMNode
    Set entry_point = objXML

    Dim myNodes As IXMLDOMNodeList
    Dim myChildNodes As IXMLDOMNodeList
    Dim myElement As IXMLDOMElement
    Dim myNode As IXMLDOMNode
    Dim myChildNode As IXMLDOMNode
    Dim nNode As Integer
    Dim nChildNode As Integer
    Set myNodes = entry_point.SelectNodes("//values")
    If myNodes.Length > 0 Then
        For nNode = 0 To myNodes.Length - 1
            Set myNode = myNodes(nNode)
            If myNode Is Nothing Then
            Else
                Set myChildNodes = myNode.ChildNodes ' Get the children of the first node.
                For nChildNode = 0 To myChildNodes.Length - 1
                    Debug.Print myChildNodes(nChildNode).Text
                    Debug.Print myChildNodes(nChildNode).Attributes.getNamedItem("code").Text
                Next nChildNode
            End If
        Next nNode
    Else
        Debug.Print "No nodes found."
    End If

End Sub

答案 1 :(得分:2)

使用HTML或XML元素的关键是使用LocalsWatch窗口浏览元素&#39; s&#39;属性。子项目将位于childNodechildrenitem个集合中。我还将在Chrome中打开文档,单击我的目标元素,并在适用时使用Copy XPath。我可以使用XPath来追踪我的目标元素。

在此示例中,我将Stop放在设置目标节点的行之后。接下来,我深入了解节点的属性(在Immediate Window中进行测试),直到找到我正在寻找的属性。

enter image description here

Sub TestStub()
    Const XMLTEST = "<values>" & _
          "<value code=""1"">A</value>" & _
          "<value code=""2"">B</value>" & _
          "<value code=""3"">C</value>" & _
          "</values>"
    Dim objXML As Object, node As Object

    Set objXML = CreateObject("MSXML2.DOMDocument")

    If Not objXML.LoadXML(XMLTEST) Then  'strXML is the string with XML'
        Err.Raise objXML.parseError.ErrorCode, , objXML.parseError.reason

    Else
        Set node = objXML.SelectSingleNode("values")
        Stop

    End If
End Sub

更新:如何使用childNodes

测试Immediate Window集合中的项目的循环

enter image description here