How to parse XML using vba

前端 未结 8 1089
不思量自难忘°
不思量自难忘° 2020-11-22 08:46

I work in VBA, and want to parse a string eg



        
8条回答
  •  不思量自难忘°
    2020-11-22 09:23

    This is an example OPML parser working with FeedDemon opml files:

    Sub debugPrintOPML()
    
    ' http://msdn.microsoft.com/en-us/library/ms763720(v=VS.85).aspx
    ' http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.selectnodes.aspx
    ' http://msdn.microsoft.com/en-us/library/ms256086(v=VS.85).aspx ' expressions
    ' References: Microsoft XML
    
    Dim xmldoc As New DOMDocument60
    Dim oNodeList As IXMLDOMSelection
    Dim oNodeList2 As IXMLDOMSelection
    Dim curNode As IXMLDOMNode
    Dim n As Long, n2 As Long, x As Long
    
    Dim strXPathQuery As String
    Dim attrLength As Byte
    Dim FilePath As String
    
    FilePath = "rss.opml"
    
    xmldoc.Load CurrentProject.Path & "\" & FilePath
    
    strXPathQuery = "opml/body/outline"
    Set oNodeList = xmldoc.selectNodes(strXPathQuery)
    
    For n = 0 To (oNodeList.length - 1)
        Set curNode = oNodeList.Item(n)
        attrLength = curNode.Attributes.length
        If attrLength > 1 Then ' or 2 or 3
            Call processNode(curNode)
        Else
            Call processNode(curNode)
            strXPathQuery = "opml/body/outline[position() = " & n + 1 & "]/outline"
            Set oNodeList2 = xmldoc.selectNodes(strXPathQuery)
            For n2 = 0 To (oNodeList2.length - 1)
                Set curNode = oNodeList2.Item(n2)
                Call processNode(curNode)
            Next
        End If
            Debug.Print "----------------------"
    Next
    
    Set xmldoc = Nothing
    
    End Sub
    
    Sub processNode(curNode As IXMLDOMNode)
    
    Dim sAttrName As String
    Dim sAttrValue As String
    Dim attrLength As Byte
    Dim x As Long
    
    attrLength = curNode.Attributes.length
    
    For x = 0 To (attrLength - 1)
        sAttrName = curNode.Attributes.Item(x).nodeName
        sAttrValue = curNode.Attributes.Item(x).nodeValue
        Debug.Print sAttrName & " = " & sAttrValue
    Next
        Debug.Print "-----------"
    
    End Sub
    

    This one takes multilevel trees of folders (Awasu, NewzCrawler):

    ...
    Call xmldocOpen4
    Call debugPrintOPML4(Null)
    ...
    
    Dim sText4 As String
    
    Sub debugPrintOPML4(strXPathQuery As Variant)
    
    Dim xmldoc4 As New DOMDocument60
    'Dim xmldoc4 As New MSXML2.DOMDocument60 ' ?
    Dim oNodeList As IXMLDOMSelection
    Dim curNode As IXMLDOMNode
    Dim n4 As Long
    
    If IsNull(strXPathQuery) Then strXPathQuery = "opml/body/outline"
    
    ' http://msdn.microsoft.com/en-us/library/ms754585(v=VS.85).aspx
    xmldoc4.async = False
    xmldoc4.loadXML sText4
    If (xmldoc4.parseError.errorCode <> 0) Then
       Dim myErr
       Set myErr = xmldoc4.parseError
       MsgBox ("You have error " & myErr.reason)
    Else
    '   MsgBox xmldoc4.xml
    End If
    
    Set oNodeList = xmldoc4.selectNodes(strXPathQuery)
    
    For n4 = 0 To (oNodeList.length - 1)
        Set curNode = oNodeList.Item(n4)
        Call processNode4(strXPathQuery, curNode, n4)
    Next
    
    Set xmldoc4 = Nothing
    
    End Sub
    
    Sub processNode4(strXPathQuery As Variant, curNode As IXMLDOMNode, n4 As Long)
    
    Dim sAttrName As String
    Dim sAttrValue As String
    Dim x As Long
    
    For x = 0 To (curNode.Attributes.length - 1)
        sAttrName = curNode.Attributes.Item(x).nodeName
        sAttrValue = curNode.Attributes.Item(x).nodeValue
        'If sAttrName = "text"
        Debug.Print strXPathQuery & " :: " & sAttrName & " = " & sAttrValue
        'End If
    Next
        Debug.Print ""
    
    If curNode.childNodes.length > 0 Then
        Call debugPrintOPML4(strXPathQuery & "[position() = " & n4 + 1 & "]/" & curNode.nodeName)
    End If
    
    End Sub
    
    Sub xmldocOpen4()
    
    Dim oFSO As New FileSystemObject ' Microsoft Scripting Runtime Reference
    Dim oFS
    Dim FilePath As String
    
    FilePath = "rss_awasu.opml"
    Set oFS = oFSO.OpenTextFile(CurrentProject.Path & "\" & FilePath)
    sText4 = oFS.ReadAll
    oFS.Close
    
    End Sub
    

    or better:

    Sub xmldocOpen4()
    
    Dim FilePath As String
    
    FilePath = "rss.opml"
    
    ' function ConvertUTF8File(sUTF8File):
    ' http://www.vbmonster.com/Uwe/Forum.aspx/vb/24947/How-to-read-UTF-8-chars-using-VBA
    ' loading and conversion from Utf-8 to UTF
    sText8 = ConvertUTF8File(CurrentProject.Path & "\" & FilePath)
    
    End Sub
    

    but I don't understand, why xmldoc4 should be loaded each time.

提交回复
热议问题