VBA XML解析-通过子节点循环

VBA XML解析-通过子节点循环,xml,excel,vba,Xml,Excel,Vba,这是我第一次尝试使用VBA解析XML文件,因此我可能忽略了明显的问题; 我已经可以打印这个了: <values> <value code="1">A</value> <value code="2">B</value> <value code="3">C</value> </values> ,其中值是其父变量 但我不知道如何循环通过值的子项,并打印“1A”、“2B”、“3C”对

这是我第一次尝试使用VBA解析XML文件,因此我可能忽略了明显的问题; 我已经可以打印这个了:

<values>
    <value code="1">A</value>
    <value code="2">B</value>
    <value code="3">C</value>
</values>
,其中
是其父
变量

但我不知道如何循环通过
值的子项,并打印“1A”、“2B”、“3C”对


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

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

我建议您特别注意XPath变量“//value”和选择器,如.getNamedItem(“code”)——您需要熟悉更多这些变量,才能熟练地进行XML解析。幸运的是,很多这方面的知识都会转化为HTML解析,因此这是一项有用的技能

在本例中,我选择了所有值节点。遍历它们就像根据节点数组的长度执行for循环并使用.item(i)调用一样简单

选项显式
子测试()
将strXml设置为字符串
strXml=“ABC”
Dim objXML作为MSXML2.DOMDocument60
设置objXML=New MSXML2.DOMDocument60
如果不是objXML.LoadXML(strXml),则“strXml是包含XML的字符串”
Err.Raise objXML.parseError.ErrorCode,objXML.parseError.reason
如果结束
作为IXMLDOMDONDE的Dim入口点
设置入口点=objXML
将myNodes设置为IXMLDOMNodeList
Dim myElement作为IXmlDoMeElement
将myNode设置为IXMLDOMNode
作为整数的Dim nNode
设置myNodes=entry\u point。选择节点(//value)
如果myNodes.Length>0,则
对于nNode=0到myNodes.Length
设置myNode=myNodes(nNode)'获取第一个节点。
如果myNode什么都不是,那么
其他的
Debug.Print myNode.Text
Debug.Print myNode.Attributes.getNamedItem(“代码”).Text
如果结束
下一个nNode
其他的
调试。打印“未找到节点”
如果结束
端接头
这里是另一种情况,我选择所有值节点,然后遍历每个值节点的子节点(假设所有值节点都只有值子节点)

选项显式
子测试()
将strXml设置为字符串
strXml=“ABC”
Dim objXML作为MSXML2.DOMDocument60
设置objXML=New MSXML2.DOMDocument60
如果不是objXML.LoadXML(strXml),则“strXml是包含XML的字符串”
Err.Raise objXML.parseError.ErrorCode,objXML.parseError.reason
如果结束
作为IXMLDOMDONDE的Dim入口点
设置入口点=objXML
将myNodes设置为IXMLDOMNodeList
将myChildNodes设置为IXMLDOMNodeList
Dim myElement作为IXmlDoMeElement
将myNode设置为IXMLDOMNode
将myChildNode设置为IXMLDOMNode
作为整数的Dim nNode
Dim nChildNode为整数
设置myNodes=entry\u point。选择节点(//值)
如果myNodes.Length>0,则
对于nNode=0到myNodes。长度为-1
设置myNode=myNodes(nNode)
如果myNode什么都不是,那么
其他的
设置myChildNodes=myNode.ChildNodes'获取第一个节点的子节点。
对于nChildNode=0到myChildNodes.Length-1
调试.打印myChildNodes(nChildNode).Text
Debug.Print myChildNodes(nChildNode).Attributes.getNamedItem(“代码”).Text
下一个nChildNode
如果结束
下一个nNode
其他的
调试。打印“未找到节点”
如果结束
端接头

使用HTML或XML元素的关键是使用
局部变量
监视
窗口浏览元素的属性。子项将位于
子节点
子节点
集合中。我还将在Chrome中打开文档,单击我的目标元素,并在适用时使用Copy XPath。我可以让他们使用XPath跟踪我的目标元素

在本例中,我将
Stop
放在设置目标节点的行之后。接下来,我向下钻取节点的属性(在
即时窗口中测试),直到找到我要查找的属性

子测试存根()
Const XMLTEST=”“&_
"A"及_
"B"及_
"C"及_
""
Dim objXML作为对象,节点作为对象
设置objXML=CreateObject(“MSXML2.DOMDocument”)
如果不是objXML.LoadXML(XMLTEST),则“strXML是包含XML的字符串”
Err.Raise objXML.parseError.ErrorCode,objXML.parseError.reason
其他的
Set node=objXML.SelectSingleNode(“值”)
停止
如果结束
端接头
更新:如何使用
即时窗口测试通过
childNodes
集合中的项的循环


如果我“按原样”运行代码,则在声明
objXML
变量时,我会出现“用户定义类型未定义”错误。是否添加了xml引用?O_ono,没有看到编辑:)。但是如果我添加它并与其他人共享代码,他们是否也需要自己添加它?这可能不是一个选项,不幸的是,我通过将所有变量
声明为Object
,并设置
Set objXML=CreateObject(“Microsoft.XMLDOM”)
避免了添加引用的需要,但这并不能解决具体问题,它概述了一个很好的程序,供业余程序员在处理类似于网络中打开的情况时使用question@horace_vr不管是好是坏,这是我的意图。我本应该继续创建循环,但Cody G.已经为您提供了正确的答案。@horace\u vr我继续,用循环的
和每个循环的
演示更新了我的答案。
Debug.Print Variable.SelectSingleNode("values").XML
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
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
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