Tim Hastings - NonHostile (because there's no need)

Weblog and collection of geeky articles.

  Home :: Who? :: Contact :: Links :: Subscribe subscribe
More Industrial Revelations with Mark Williams - God Be Praised!!Privacy Risk With Internet ExplorerNow Witness the Power of This Fully Armed and Operational Debian NSLU2


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:

&lt; 

&gt; 

&amp; 

&apos; 

&quot; 

If writing XML in a text editor, or seaching a DOM using XPath, you need to be aware of these encodings.

    <food name="fish &amp; chips"/>
    Set objElem = objXML.selectSingleNode("//*[@name=""fish &amp; 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.


Iterating Elements

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



1530 comments, Visual Basic 6, Sunday, May 16, 2004 11:19

Timeline Navigation for Visual Basic 6 posts
VB6: Variant Stack Class (Code Library) (made 4 days later)
VB6: XML and How To Read It With Visual Basic (this post, made Sunday, May 16, 2004 11:19)
VB6: Convert HTML into Searchable Text using Regular Expressions (made 1 week earlier)


Comments
Hi, I'm trying to populate my program with information extracted from an XML file and thought I'd cracked it with your example shown but unfortunately I seem to be at a loss, below is an example of my XML

<example>
<dob>07/08/1967</dob>
<surname>Smith</surname>
<forename>David</forename>
<books><book>title1</book><book>title2</book><book>title3</book></books>
</example>

what I want to do is read the XML file and the results would populate the following fields, for example

forename.Text = David
surname.Text = Smith
dob.Text = 07/08/1967

and a combo list box would have the variable length books xml extract would contain

title1
title2
title3

I'm sure its possible but I seem to have tried endlessly to acheive the result, and I can't seem to find any examples or source code that shows me how to achieve it.

I would be very happy if you could take the time to show me how it is possible, if possible with some documented code so it will hopefully sink in and I finally understand it

Many thanks, hope to hear from you on the meail given

Posted by: Colin on Saturday, November 18, 2006 00:11
Hi Colin!

I've sent you a demo project which does what you're asking. For anyone else interested, the code looks like this:

' take an XML document and populate the form
' with its contents. This expects the document to be structured
' like the example
Private Sub PopulateForm(ByVal xmlPerson As MSXML2.DOMDocument)

Dim xmlElem As IXMLDOMElement
Dim xmlBooks As IXMLDOMNodeList

' get dob
Set xmlElem = xmlPerson.selectSingleNode("example/dob")
If Not xmlElem Is Nothing Then
Me.txtDOB.Text = xmlElem.Text
End If

' set surname
Set xmlElem = xmlPerson.selectSingleNode("example/surname")
If Not xmlElem Is Nothing Then
Me.txtSurname.Text = xmlElem.Text
End If

' set firstname
Set xmlElem = xmlPerson.selectSingleNode("example/forename")
If Not xmlElem Is Nothing Then
Me.txtForename.Text = xmlElem.Text
End If

' get all books and add to the combo box
Set xmlBooks = xmlPerson.selectNodes("example/books/book")
Me.cboBooks.Clear
For Each xmlElem In xmlBooks
Me.cboBooks.AddItem xmlElem.Text
Next

End Sub

The source code for this demo can be downloaded from here: http://www.nonhostile.com/res/vb6/XmlDemo.zip

Posted by: Tim on Saturday, November 18, 2006 21:48
Hi All,

This is my first visit to this site, and it seems pretty neat. Anyways, i'm having some difficulty with XML and VB. I can read the XML file perfectly (thanks to the above article), but i'm having trouble inserting into an existing XML document.

Any help will be greatly appreciated (maybe an example, if possible plz>),

Thanks in advance!

Yazin (aka Zync)

Posted by: Zync Oxide on Tuesday, March 6, 2007 06:36
Great article, nice one

Posted by: James on Monday, September 10, 2007 12:54
Looks like the only article online covering the subject. Really helped me out.

Thanx

Fargii

Posted by: Fargii on Tuesday, September 11, 2007 14:09
Thanks you very much

Hope the some day I could repay you

Posted by: dudi on Thursday, October 11, 2007 10:23
Thanks a ton! After searching hi and low, this is the first page I've read that actually makes sense.

Posted by: Iain Grant on Friday, November 9, 2007 20:13
thanks a lot keep posting about vb and xml

Posted by: peegee on Saturday, November 10, 2007 04:32
EXCELLENT WAS HELP FULL, THANK YOU

Posted by: xml on Saturday, January 26, 2008 03:35
nice article, thanks

Posted by: peegee on Sunday, February 3, 2008 16:45
Hi there,

Can you show me how to extract data from (EN-GB and HU-01) fields to ListView (to mention, the XML file has more that 50-60 nodes)???

<?xml version="1.0" ?>
<tmx version="version 1.1">

<body>

<tu>
<prop type="Txt::Doc. No.">21973A1221(01)</prop>
<tuv lang="EN-GB">
<seg>Your Excellency,</seg>
</tuv>
<tuv lang="BG-01">
<seg>Господин Посланик,</seg>
</tuv>
<tuv lang="CS-01">
<seg>Výměna dopisů,</seg>
</tuv>
<tuv lang="HU-01">
<seg>Nagykövet Úr!</seg>
</tuv>
<tuv lang="LT-01">
<seg>Jūsų Ekscelencija,</seg>
</tuv>
<tuv lang="LV-01">
<seg>Jūsu ekselence!</seg>
</tuv>
<tuv lang="MT-01">
<seg>L-Eċellenza Tiegħek,</seg>
</tuv>
<tuv lang="PL-01">
<seg>Wasza Ekscelencjo,</seg>
</tuv>
<tuv lang="SK-01">
<seg>Vaša excelencia,</seg>
</tuv>
<tuv lang="SL-01">
<seg>Vaša ekscelenca,</seg>
</tuv>
</tu>

</body>
</tmx>

Please help me!!!!

Posted by: Viktor on Tuesday, February 5, 2008 13:45
Very good site and great example...:)

Posted by: Amit Dror on Sunday, April 27, 2008 19:30
Hi:

Thank you for the samples.

I have big XML file with multi layers of data just like this one:
Account
InvoiceHeader
Address Details
Group
Sub_Account
Sub_Account_Header
Address_Details
Product_Group
Service_grp_chrg_summary
Product
Service
Charge_Details
Charge1
Charge2
Charge3
Service_Header
..

I was able to extract all attributes of Service but I am interested in 1 attribute of Service, 1 from Charge1-4 and
2 from Service_header - how do I perform this.

Please let me know if we have any options either using xPath or xsl.

Thank you in advance.
Ramesh V

Posted by: Ramesh V on Wednesday, May 21, 2008 18:51
Nice article I got unblocked after a long search. Thanks

Posted by: Novice on Wednesday, June 4, 2008 14:50
Hi:
Awesome website really helpful.. But I am getting data from a website which shows up as XML...
How do I retrieve data from there?
it looks like this:
http://geocoder.us/service/rest/geocode?address=22%20W%2074TH%20ST,NEW%20YORK,NY%2010023
which brings up


<rdf:RDF>

<geo:Point rdf:nodeID="aid98160201">
<dc:description>22 W 74th St, New York NY 10023</dc:description>
<geo:long>-73.975720</geo:long>
<geo:lat>40.777796</geo:lat>
</geo:Point>
</rdf:RDF>

Thanks

Posted by: Zishan R on Thursday, July 31, 2008 20:31
Hi, I am beginning to write a e-prescibing program for pharmacy and hope to be able to stick with VB 6.0 to match other programs written. What I need to do is the following:
1. pass data to a XML wrapper
2. extract data from a XML wrapper
3. decode received messages, encode sent messages in 64 bit security.
I am following what is happening in your example above but not sure I can get everything to work under VB6. Any suggestions on the possibilities?

Posted by: Robert Komjathy on Wednesday, September 17, 2008 17:39
I am writing a complete wrapper for this, particurlarly for GEO Rss feeds and Synchronisation possibilities of these. All in VB6. I'll release these public, if there is any interest... petri

Posted by: Petri on Thursday, September 18, 2008 14:59
hi, i have used this example given and i have set the reference to xml v2,6 ,but when i run the vb6 code its giving error the for " Dim objElem As MSXML.IXMLDOMElement" user defined type not defined. Can any one help me do i need to add any other reference.

Posted by: anil on Friday, October 24, 2008 11:12
interesting article!

minor correction:

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 MSXML.IXMLDOMElement --> SHOULD BE:

Dim objElem As MSXML2.IXMLDOMElement


Posted by: Gordon MacDonald on Saturday, January 10, 2009 23:39
Wow. 2009 and people are still using VB6. Great stuff.

Thanks for the article.

(no I won't ask you to solve my XML problem, but the article was a good crash course).

Posted by: Mach2 on Wednesday, January 14, 2009 21:20
Thanks for this great introduction! You made my day!
xml running in vb6.. another reason why not to upgrade :D

Posted by: Andre on Thursday, January 15, 2009 22:24
Great article.

But how can i implement a like search to fetch values like we do in Sql query.

For e.g. all values starting with 'yay'

Posted by: Mohit on Wednesday, February 4, 2009 06:04
another great article, thanks!

Posted by: Ken on Friday, February 27, 2009 18:15
hi

Posted by: lo2i on Tuesday, April 28, 2009 17:33
I am running VB6 and XP latest service pack. The first 3 textboxes are populated with David, Smith, 07/08/1967 but the combo box is filled with title1, title2, title3 I traced it out and Me.cboBooks.AddItem xmlElem.Text is indeed setting the cboBoos elements to these text strings. Anyone else see this?

Posted by: D.A. on Wednesday, May 6, 2009 18:18
Nevermind - I have too many VB projects open at once! THis is the correct behavior!!!!!!!!!

Posted by: D.A. on Wednesday, May 6, 2009 18:21
excellent tutorial I found after searched ton of sites
Thank you so much "Tim"
hope you will explain how to append and edit data on xml file
thnks again

Posted by: chandana on Wednesday, July 1, 2009 05:10
Thanks Tim... your explaination and examples helped a lot to solve my little problem.

Posted by: Darrel on Thursday, July 2, 2009 23:46
Hi,

I am looking for a vb6 example of hopw to pull an xml feed from a web address into my vb6 app.

I have an address which I am told will push me a file, but I've no idea where to start on the vb side of it.

Thanks.

Posted by: Tom on Friday, August 21, 2009 08:13
I now have an xml file on my own server and I can see it is ther but I still need to find vb6 code to grab this, anyone care to help me out withthe firsts teps?

Posted by: Tom on Wednesday, August 26, 2009 20:17
Thanks. Nice Article.

Posted by: Evans on Monday, October 12, 2009 10:04
Excellent, clear and to the point, best one I have seen so far

Posted by: Majella Strinati on Tuesday, December 1, 2009 17:02
Fantastic, very well done

Posted by: Pat Rourke on Monday, February 1, 2010 10:30
lol

Posted by: on Friday, March 19, 2010 02:01
hi there guys, so nice to see such good advice on vb6 & xml.
i am an amatur in programming in vb6 which is why i'm going to ask for some help. My project mate is sending me some data in xml format from her C programming, but the problem is i have already done mine in vb6.

so my question is how do i extract the information from xml and put them into my array in vb6. i read the above example from colin

"
Dim xmlElem As IXMLDOMElement
Dim xmlBooks As IXMLDOMNodeList

' get dob
Set xmlElem = xmlPerson.selectSingleNode("example/dob")
If Not xmlElem Is Nothing Then
Me.txtDOB.Text = xmlElem.Text
End If
"

what i would like to use the same method to get a value for my array, replacing the xmlElem with grid(1,0). however in the first place my array is already declare as an integer. is the same method feasible.

Posted by: Goat Kua on Wednesday, March 24, 2010 18:00
oh so sorry, the above example was done by tim, not colin. my apologies

Posted by: Goat Kua on Wednesday, March 24, 2010 18:02
HOW TO Save AND Readable XML file in Visual Basic6.0 program

Posted by: Jasen Barroma on Monday, April 12, 2010 14:28
how to program in Visual BAsic6.0 that can save and Readable XMl file thx.... can you give me ah sample SOurce code thx

Posted by: Jasen Barroma on Monday, April 12, 2010 14:29
can anybody help me??

Posted by: Jasen Barroma on Monday, April 12, 2010 14:33

Post a Comment
Name:  Home page and email address are optional.
  Email addresses will not be displayed or spammed!
Remember these details
Email:
Home Page:
Comment:
Comments cannot contain HTML, URLs will be formatted into hyperlinks.
I reserve the right to remove any comments for any reason.