Visual Basic was developed before XML became mainstream so the language does not provide built-in support like languages such as C# or VB.Net. To quickly add support for XML to your VB6 application you will need to rely on an external library to do all the XML heavy lifting for you. Luckily, Microsoft provides a library that we can use for free, and as a bonus it is widely deployed.
To add support for XML in your VB6 application, first, you need to add a reference to: Microsoft XML, v2.6 or later. This version is the most widely distributed and carries all basic functionality needed, although later versions offer more functionality such as XSD Validation.
<example> <node name="hello"/> <group name="something"> <another value="yay"/> </group> </example>
Suppose we have some example XML as a string, or as a file, what we want to do is interrogate and manipulate it. To do this, we can use an object provided called the DOMDocument. The DOM stands for Document Object Model, so its strangely named the Document Object Model Document.
Dim objXML As MSXML2.DOMDocument
There are two ways of loading XML into the DOM, the right one to use depends on where your XML is. If you already have the XML in a variable, then loadXML is the method to use. It your XML is in a file or stream, then load is your man. Each is a function that will return true if successful.
Dim objXML As MSXML2.DOMDocument Dim strXML As String Set objXML = New MSXML2.DOMDocument ' put some XML in a variable - the double double quotes are ' VB6's string constant encoding of quotes strXML = "<example><node name=""hello""/><group name=""something""><another value=""yay""/></group></example>" If Not objXML.loadXML(strXML) Then Err.Raise objXML.parseError.errorCode, , objXML.parseError.reason End If
If unsuccessful, then the parseError property will contain information about what went wrong.
Alternatively, if your XML is contained in a file, then the load method can be used in the same way as above.
If objXML.load("c:\myExample.xml") Then ...
Nice one, we've got our XML loaded. Probably the best way to learn what's going on is to slap a break point in the code and explore the objects and properties in the variables window. But here are the things I find most useful.
Finding Nodes using XPath
XPath is a language for describing sets of nodes contained within an XML document. Its like SQL for XML. I'll only go into the basics of XPath for this article.
Dim objElem As MSXML2.IXMLDOMElement ' find the first occurance of an element called 'another' Set objElem = objXML.selectSingleNode("//another") Debug.Print objElem.getAttribute("value") ' find the first element with a name = 'something' ' again, the double quotes are VB's string constant encoding of " Set objElem = objXML.selectSingleNode("//*[@name=""something""]") Debug.Print objElem.getAttribute("name")
XML Encoding special characters
There are certain characters that would confuse an XML parser if it encountered them. These are: < > & ' and "
These need to be encoded if they are to appear in the data part of your XML documents. Their encodings are:
If writing XML in a text editor, or seaching a DOM using XPath, you need to be aware of these encodings.
<food name="fish & chips"/>
Set objElem = objXML.selectSingleNode("//*[@name=""fish & chips""]")
Including chunks of raw text using CDATA
If you want to place large amounts of text in an XML file and do not want to encoding all the special characters as shown above, then you can use CDATA blocks. They start with <![CDATA[ and ends with ]]> and they look like this:
<MyXML> <Name>Hello</Name> <Message><![CDATA[ Any text can go here and it can include the forbidden characters < > & ' and " without encoding them. ]]> </Message> </MyXML>
You must make sure that your raw text does not contain ]]>
If it does you must break your message into two consecutive CDATA blocks which splits this terminator.
Another really useful trick is iterating though sub-elements of an element. Once you've got your element via select, you can do the following:
Dim objSub As MSXML2.IXMLDOMElement ' get the example node Set objElem = objXML.selectSingleNode("example") ' iterate its sub-nodes For Each objSub In objElem.childNodes Debug.Print objSub.xml Next
XPath clauses, The SQL Where Clause of XML
All nodes within a document can be referred to via XPath queries. XPath also allows you to specify criteria, for example, fetch the element 'product' with the attribute 'code' = 1234. This is achieved by placing constraints within square brackets.
' get first product with code 123 Set objElem = objXML.selectSingleNode("//product[@code=""123""]") ' find all products with a cost greater than 10 Set objList = objXML.selectSingleNode("//product[@cost>10]") For Each objSub In objList Debug.Print objSub.xml Next
It should be noted that the MSXML DOM does not perform any kind of indexing on attributes and some XPath queries like 'find me all products with a cost greater than 10' will perform a trawl through the entire object model. For small XML documents this will be very quick, but for massive documents, this could be quite timely. See Strategies for Indexing Elements of a Large XML DOM in Visual Basic for an example of quickly accessing elements within a large DOM.
More useful than that is using XPath to find a set of matching elements, then iterate through that.
' iterate through all group elements in the document For Each objSub In objXML.selectNodes("//group") Debug.Print objSub.xml Next
Beware of Nulls
If you use the getAttribute method of an element, if that element does not have the attribute, it will return Null. It is important to use VB's IsNull function to test for this otherwise you will get lots of invalid use of null errors.
' find any element whose name = "something" Set objElem = objXML.selectSingleNode("//*[@name=""something""]") ' test to see if 'monkey' attribute is null If Not IsNull(objElem.getAttribute("monkey")) Then Debug.Print objElem.getAttribute("monkey") End If