Search code examples
xmlvbaexcelmsxml

How do I import XML data using Excel VBA?


I'm trying to import data from an XML file like this:

<library>
<book>
<title>aaa</title>
<author>aaa-author</author>
</book>
<book>
<title>bbb</title>
<author>bbb-author</author>
</book>
<book>
<title>ccc</title>
</book>
</library>

(note that the third book has no value for the author)

I would like to obtain an Excel table where each book's data are displayed on one row. The problem is that I do not understand how I have to loop on the book nodes to obtain their children values.

I'm working on code like this:

Set mainWorkBook = ActiveWorkbook
Set oXMLFile = CreateObject("Microsoft.XMLDOM")
XMLFileName = "C:\example.xml"
oXMLFile.Load (XMLFileName)
Set Books = oXMLFile.SelectNodes("/book")
For i = 0 To (Books.Length - 1)
   ' I cannot understand this part
Next

Solution

  • Add a reference (Tools -> References ...) to Microsoft XML 6.0. This will allow you to have typed variables (Dim book As IXMLDOMNode), which will give you Intellisense.

    Then you can use the following code, which iterates through all the book elements, saves the title and author into a 2-dimensional array (if they are available), then pastes the array into an Excel worksheet:

    Dim oXMLFile As New DOMDocument60
    Dim books As IXMLDOMNodeList
    Dim results() As String
    Dim i As Integer, booksUBound As Integer
    Dim book As IXMLDOMNode, title As IXMLDOMNode, author As IXMLDOMNode
    
    'Load XML from the file
    oXMLFile.Load "C:\example.xml"
    
    'Get a list of book elements
    Set books = oXMLFile.SelectNodes("/library/book")
    booksUBound = books.Length - 1
    
    'Create a two-dimensional array to hold the results
    ReDim results(booksUBound, 1)
    
    'Iterate through all the book elements, putting the title and author into the array, when available
    For i = 0 To booksUBound
        Set book = books(i) 'A For Each loop would do this automatically, but we need the
                            'index to put the values in the right place in the array
        Set title = book.SelectSingleNode("title")
        If Not title Is Nothing Then results(i, 0) = title.Text
        Set author = book.SelectSingleNode("author")
        If Not author Is Nothing Then results(i, 1) = author.Text
    Next
    
    'Paste the results into the worksheet
    Dim wks As Worksheet
    Set wks = ActiveSheet
    wks.Range(wks.Cells(1, 1), wks.Cells(books.Length, 2)) = results
    

    Links:

    References: