I work in VBA, and want to parse a string eg
<PointN xsi:type='typens:PointN'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:xs='http://www.w3.org/2001/XMLSchema'>
<X>24.365</X>
<Y>78.63</Y>
</PointN>
and get the X & Y values into two separate integer variables.
I’m a newbie when it comes to XML, since I’m stuck in VB6 and VBA, because of the field I work in.
How do I do this?
Trevor Reid
3,1824 gold badges27 silver badges46 bronze badges
asked Aug 14, 2008 at 16:41
Devdatta TengsheDevdatta Tengshe
3,9659 gold badges45 silver badges59 bronze badges
1
Thanks for the pointers.
I don’t know, whether this is the best approach to the problem or not, but here is how I got it to work.
I referenced the Microsoft XML, v2.6 dll in my VBA, and then the following code snippet, gives me the required values
Dim objXML As MSXML2.DOMDocument
Set objXML = New MSXML2.DOMDocument
If Not objXML.loadXML(strXML) Then 'strXML is the string with XML'
Err.Raise objXML.parseError.ErrorCode, , objXML.parseError.reason
End If
Dim point As IXMLDOMNode
Set point = objXML.firstChild
Debug.Print point.selectSingleNode("X").Text
Debug.Print point.selectSingleNode("Y").Text
bluish
25.9k27 gold badges120 silver badges179 bronze badges
answered Aug 14, 2008 at 17:40
Devdatta TengsheDevdatta Tengshe
3,9659 gold badges45 silver badges59 bronze badges
1
Add reference Project->References Microsoft XML, 6.0 and you can use example code:
Dim xml As String
xml = "<root><person><name>Me </name> </person> <person> <name>No Name </name></person></root> "
Dim oXml As MSXML2.DOMDocument60
Set oXml = New MSXML2.DOMDocument60
oXml.loadXML xml
Dim oSeqNodes, oSeqNode As IXMLDOMNode
Set oSeqNodes = oXml.selectNodes("//root/person")
If oSeqNodes.length = 0 Then
'show some message
Else
For Each oSeqNode In oSeqNodes
Debug.Print oSeqNode.selectSingleNode("name").Text
Next
End If
be careful with xml node //Root/Person is not same with //root/person, also selectSingleNode(«Name»).text is not same with selectSingleNode(«name»).text
SierraOscar
17.5k6 gold badges41 silver badges68 bronze badges
answered Oct 13, 2015 at 13:29
No NameNo Name
6996 silver badges14 bronze badges
1
You can use a XPath Query:
Dim objDom As Object '// DOMDocument
Dim xmlStr As String, _
xPath As String
xmlStr = _
"<PointN xsi:type='typens:PointN' " & _
"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " & _
"xmlns:xs='http://www.w3.org/2001/XMLSchema'> " & _
" <X>24.365</X> " & _
" <Y>78.63</Y> " & _
"</PointN>"
Set objDom = CreateObject("Msxml2.DOMDocument.3.0") '// Using MSXML 3.0
'/* Load XML */
objDom.LoadXML xmlStr
'/*
' * XPath Query
' */
'/* Get X */
xPath = "/PointN/X"
Debug.Print objDom.SelectSingleNode(xPath).text
'/* Get Y */
xPath = "/PointN/Y"
Debug.Print objDom.SelectSingleNode(xPath).text
SierraOscar
17.5k6 gold badges41 silver badges68 bronze badges
answered Dec 30, 2014 at 11:24
mvanlemvanle
1,77720 silver badges19 bronze badges
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.
SierraOscar
17.5k6 gold badges41 silver badges68 bronze badges
answered May 9, 2010 at 2:19
DK.DK.
911 silver badge2 bronze badges
Update
The procedure presented below gives an example of parsing XML with VBA using the XML DOM objects. Code is based on a beginners guide of the XML DOM.
Public Sub LoadDocument()
Dim xDoc As MSXML.DOMDocument
Set xDoc = New MSXML.DOMDocument
xDoc.validateOnParse = False
If xDoc.Load("C:My Documentssample.xml") Then
' The document loaded successfully.
' Now do something intersting.
DisplayNode xDoc.childNodes, 0
Else
' The document failed to load.
' See the previous listing for error information.
End If
End Sub
Public Sub DisplayNode(ByRef Nodes As MSXML.IXMLDOMNodeList, _
ByVal Indent As Integer)
Dim xNode As MSXML.IXMLDOMNode
Indent = Indent + 2
For Each xNode In Nodes
If xNode.nodeType = NODE_TEXT Then
Debug.Print Space$(Indent) & xNode.parentNode.nodeName & _
":" & xNode.nodeValue
End If
If xNode.hasChildNodes Then
DisplayNode xNode.childNodes, Indent
End If
Next xNode
End Sub
Nota Bene — This initial answer shows the simplest possible thing I could imagine (at the time I was working on a very specific issue) .
Naturally using the XML facilities built into the VBA XML Dom would be
much better. See the updates above.
Original Response
I know this is a very old post but I wanted to share my simple solution to this complicated question. Primarily I’ve used basic string functions to access the xml data.
This assumes you have some xml data (in the temp variable) that has been returned within a VBA function. Interestingly enough one can also see how I am linking to an xml web service to retrieve the value. The function shown in the image also takes a lookup value because this Excel VBA function can be accessed from within a cell using = FunctionName(value1, value2) to return values via the web service into a spreadsheet.
openTag = ""
closeTag = ""
' Locate the position of the enclosing tags
startPos = InStr(1, temp, openTag)
endPos = InStr(1, temp, closeTag)
startTagPos = InStr(startPos, temp, ">") + 1
' Parse xml for returned value
Data = Mid(temp, startTagPos, endPos - startTagPos)
bluish
25.9k27 gold badges120 silver badges179 bronze badges
answered Apr 21, 2011 at 16:30
Tommie C.Tommie C.
12.8k5 gold badges81 silver badges98 bronze badges
0
Here is a short sub to parse a MicroStation Triforma XML file that contains data for structural steel shapes.
'location of triforma structural files
'c:programdatabentleyworkspacetriformatf_imperialdataus.xml
Sub ReadTriformaImperialData()
Dim txtFileName As String
Dim txtFileLine As String
Dim txtFileNumber As Long
Dim Shape As String
Shape = "w12x40"
txtFileNumber = FreeFile
txtFileName = "c:programdatabentleyworkspacetriformatf_imperialdataus.xml"
Open txtFileName For Input As #txtFileNumber
Do While Not EOF(txtFileNumber)
Line Input #txtFileNumber, txtFileLine
If InStr(1, UCase(txtFileLine), UCase(Shape)) Then
P1 = InStr(1, UCase(txtFileLine), "D=")
D = Val(Mid(txtFileLine, P1 + 3))
P2 = InStr(1, UCase(txtFileLine), "TW=")
TW = Val(Mid(txtFileLine, P2 + 4))
P3 = InStr(1, UCase(txtFileLine), "WIDTH=")
W = Val(Mid(txtFileLine, P3 + 7))
P4 = InStr(1, UCase(txtFileLine), "TF=")
TF = Val(Mid(txtFileLine, P4 + 4))
Close txtFileNumber
Exit Do
End If
Loop
End Sub
From here you can use the values to draw the shape in MicroStation 2d or do it in 3d and extrude it to a solid.
SierraOscar
17.5k6 gold badges41 silver badges68 bronze badges
answered Jan 12, 2015 at 18:30
Often it is easier to parse without VBA, when you don’t want to enable macros. This can be done with the replace function. Enter your start and end nodes into cells B1 and C1.
Cell A1: {your XML here}
Cell B1: <X>
Cell C1: </X>
Cell D1: =REPLACE(A1,1,FIND(A2,A1)+LEN(A2)-1,"")
Cell E1: =REPLACE(A4,FIND(A3,A4),LEN(A4)-FIND(A3,A4)+1,"")
And the result line E1 will have your parsed value:
Cell A1: {your XML here}
Cell B1: <X>
Cell C1: </X>
Cell D1: 24.365<X><Y>78.68</Y></PointN>
Cell E1: 24.365
answered Nov 30, 2016 at 22:13
- Importance of an XML Parser
- Build XML Parser Using VBA
- Conclusion
This article will teach us how to parse XML files in VBA.
Importance of an XML Parser
As a Microsoft Excel user, it is common that you might receive some data in the form of an XML file. You will have to retrieve the information from the XML file and use it in your sheets or VBA macros according to your requirement.
A way to do this is to treat it as a text file and parse the information. But this is not an elegant way to parse XML files since the information is stored well-structured using tags, and treating it as a text file negates this concept.
Therefore, we will have to make use of an XML Parser. An XML Parser reads the XML file and retrieves the relevant data so it can be used readily.
Build XML Parser Using VBA
We can parse an XML file using VBA and convert the data into our Excel sheet. The method we will be using uses the XML DOM
implementation, short for the XML Document Object Model, and this model allows us to represent the XML file as an object we can then manipulate as required.
To start parsing your XML file through VBA, you must perform a simple sequence of steps. These are explained below.
To parse XML through VBA, you need to have MSXML.4.0
or greater on your system.
-
Add Reference to Microsoft XML
First, you need to add a reference to
Microsoft XML, V6.0
in the VBA Editor. This is how it is done:Open the VBA Editor from the Developer tab in Excel.
-
Scroll down and check
Microsoft XML, V6.0
, then click onOK
.Note that the version of Microsoft XML depends on the operating system and Microsoft Office installed on your computer.
-
Write VBA Code to Load the XML File Into
XML DOM
Suppose we have the following XML file:
<?xml version="1.0" encoding="ISO8859-1" ?> <menu> <food> <name> Halwa Puri </name> <price> $7.50 </price> <description> Halwa Puri is from Indian and Pakistani cuisines, having the sweet Halwa and the savory Puri which is a fried flatbread. </description> <calories> 900 </calories> </food> </menu>
We can use the following code to parse this XML file through VBA by making an
XML DOM
object in the following way:Sub XMLParser() Dim xDoc As New MSXML2.DOMDocument60 Dim node As IXMLDOMElement Set xDoc = New MSXML2.DOMDocument60 With xDoc .async = False .validateOnParse = True If xDoc.Load("D:VBAexample.xml") = False Then Debug.Print .parseError.reason, .parseError.ErrorCode Exit Sub End If Set node = xDoc.SelectSingleNode("//price") MsgBox node.Text End With End Sub
In the code above, we have first created a variable xDoc
of the MSXML2.DOMDocument60
type. Here, we have appended 60
at the end because we are using version 6.0
of Microsoft XML
, and without the 60
, this code will generate a compile-time error of User-defined type not found
.
Next, we have specified that we are working with the xDoc
variable using the With
statement. The .async
property defines permission for asynchronous downloads, and the .validateOnParse
property indicates if the parser should validate the XML
document.
After that, we use the .Load
function to load the specified XML
file into the DOM
variable. Here, you can change the path and file name to the one on your computer.
The next two lines are for error handling in case the XML
file is not loaded properly. To test if the loading has worked, we take one node from the file and specify its name as price
.
You should note that the node name is case-sensitive and must be specified according to your XML
file. Finally, we display the price using the node.Text
property in a message box.
Output:
This shows that the loading has worked perfectly fine.
One way to use the XML file data is to store it in an Excel sheet. Let us make a few changes to the code above to store the data in the Excel sheet:
Sub XMLParser()
Dim xDoc As New MSXML2.DOMDocument60
Set xDoc = New MSXML2.DOMDocument60
Dim list As MSXML2.IXMLDOMNodeList
Dim osh As Worksheet
Set osh = ThisWorkbook.Sheets("Sheet1")
oRow = 1
With xDoc
.async = False
.validateOnParse = True
If xDoc.Load("D:VBAexample.xml") = False Then
Debug.Print .parseError.reason, .parseError.ErrorCode
Exit Sub
End If
Set list = xDoc.SelectNodes("//price")
loopCount = 0
For Each node In list
oRow = oRow + 1
osh.Range("A" & oRow) = node.Text
Next
End With
End Sub
Here, we are retrieving all the price
nodes and storing them in the sheet. In this example, we have only one price
node that will be saved into the sheet as follows:
You can tweak the code according to your XML file and requirements.
Conclusion
This sums up our discussion on the method to parse XML
files through VBA. In this article, we have learned how to build an XML parser using XML DOM
in VBA.
In my previous articles, we discussed how VBA in Excel can be used for reporting, creating ribbons for your macros, and how to connect an Excel file as a database with SQL support. Working with a database within Excel is a very convenient feature you may use for gathering and storing of data. Nowadays, however, modern object databases and big data platforms prefer formats like JSON (Avro) or XML in general.
Definitions and Declarations
Most modern languages like Python or Ruby have standard XML parsers in-built. As VBA has been here for decades, neither much maintained, nor developed, the support is not that straight-forward. There is, however, a good tool set you may use for processing XMLs in your macros. Firstly, let’s define the objects we will work with:
Public Function ParseXML(p_path As String) As Object
Dim objDom As Object '// DOMDocument
Dim strData As String
Dim objStream As ADODB.Stream
Set objDom = CreateObject("Msxml2.DOMDocument.3.0") '// Using MSXML 3.0;
'you may use DOMDocument.4.0 for MSXML 4.0
Set objStream = New ADODB.Stream 'CreateObject("ADODB.Stream")
objStream.Charset = "UTF-8"
objStream.Open
objStream.LoadFromFile (p_path)
strData = objStream.ReadText()
objStream.Close
Set objStream = Nothing
objDom.LoadXML strData
Set ParseXML = objDom
End Function
The code is quite self-explanatory. I pasted the whole function, so feel free to use it directly as-is, just pass the source XML file path as an argument and don’t forget about error handling.
Accessing XML Data
Now let’s have a look at the functions we may use for data extraction. The basic looping through the XML nodes may be implemented as follows:
For Each listNode In rootNode.ChildNodes
If listNode.HasChildNodes Then
' do something
End If
Next listNode
Accessing the data of the actual node:
<SingleNode Id="N1" Text="NodeValue" Required="true" Look="Standard">
TheText
</SingleNode>
Would follow the below syntax:
str = listNode.BaseName ' Extracts "SingleNode" value
str = listNode.Attributes(0).Text ' Extracts "N1" value
str = listNode.Text ' Extracts "TheText" value
Other standard traversing methods you might need are also supported – for a more comprehensive overview, you may want to check this article. Node referencing:
XML representation:
<?xml version="1.0" encoding="utf-8"?>
<RootElement>
<Node ID="1">
<Node ID="1.1" />
</Node>
<Node ID="2">
<Node ID="2.1" />
<Node ID="2.2" />
<Node ID="2.3" />
<Node ID="2.4" />
</Node>
<Node ID="3" />
</RootElement>
In case you need to access a specific node directly and you don’t need control of the actual traversing, you may also use the XPath methods.
That is it for now, have fun working with your XMLs. Is there anything else you would like to know about VBA and macros in MS Office? Just drop me a message and I might discuss it in the next article. Thanks for reading!
Read XML using Excel VBA
XML is the file format that is widely used to transfer data over internet or between 2 systems with different platforms. The most widely used & familiar xml file in the internet world is the Sitemap.xml. This file has the major links to a website.
Other widely used file formats for data transfer are JSON, CSV. In this article, we are going to learn how to read the xml file using XML DOM (Data Object Model).
Excel VBA XML Parser
Using this tutorial you can build a XML parser using Excel VBA. Lets start with this step by step procedure. Open an Excel Workbook & Open VB Editor by pressing Alt + F11. Then follow these important steps.
- Add reference to “Microsoft XML, V6.0” from Excel VB editor.
- VB Editor -> Menu->Tools -> Reference
- Scroll down till Microsoft XML, V2.0 or 3.0 or 6.0 appears. The version of XML depends on the OS & Office version installed in your machine.
- Click Ok.
- Now, Copy paste the code to your VBE.
- Download a file from Internet or if you have a file already, Modify the xml file path in the code.
- Run the code by pressing F5.
'-------------------------------------------------------------------------------- 'Code by author@officetricks.com 'Visit https://officetricks.com to get more Free & Fully Functional VBA Codes '-------------------------------------------------------------------------------- Public Sub Xml_To_Excel() Dim myURL As String, sFileNamePath As String, dsh As Worksheet, osh As Worksheet Dim WinHttpReq As Object, Node As IXMLDOMNode Dim xDoc As MSXML2.DOMDocument Dim list As MSXML2.IXMLDOMNodeList 'Create XML DOM Object Set xDoc = New MSXML2.DOMDocument Set osh = ThisWorkbook.Sheets("Sheet2") oRow = 1 'This is only a sample xml file - Change the File path to your Xml file path fname = "http://www.xmlfiles.com/examples/simple.xml" 'Load Xml file to Object & Process Each node. If xDoc.Load(fname) Then Set list = xDoc.SelectNodes("//breakfast-menu/food") loopCount = 0 Application.Wait DateAdd("s", 5, Now) DoEvents For Each Node In list oRow = oRow + 1 '***Note: node names are Casesensitive*** osh.Range("A" & oRow) = Node.SelectSingleNode("name").Text osh.Range("B" & oRow) = Node.Text Next Else MsgBox "Error Occured" End If MsgBox "Process Completed" End Sub
This code uses XML DOM model to parse each node from input xml file. Then write it to the Excel file one by one.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
1
branch
0
tags
Code
-
Use Git or checkout with SVN using the web URL.
-
Open with GitHub Desktop
-
Download ZIP
Latest commit
Files
Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
VBA-XMLConverter
Status: Incomplete, Under Development
XML conversion and parsing for VBA (Excel, Access, and other Office applications).
Tested in Windows Excel 2013 and Excel for Mac 2011, but should apply to 2007+.
- For Windows-only support, include a reference to «Microsoft Scripting Runtime»
- For Mac support or to skip adding a reference, include VBA-Dictionary.
Example
Dim XML As Object Set XML = XMLConverter.ParseXML( _ "<?xml version="1.0"?>" & _ "<messages>" & _ "<message id="1" date="2014-1-1">" & _ "<from><name>Tim Hall</name></from>" & _ "<body>Howdy!</body>" & _ "</message>" & _ "</messages>" _ ) Debug.Print XML("documentElement")("nodeName") ' -> "messages" Debug.Print XML("documentElement")("childNodes")(1)("attributes")("id") ' -> "1" Debug.Print XML("documentElement")("childNodes")(1)("childNodes")(2)("text") ' -> "Howdy!" Debug.Print XMLConverter.ConvertToXML(XML) ' -> "<?xml version="1.0"?><messages>...</messages>"