logo
vbRad Home
Source Code
Book Reviews
Forum
Links
About Us
Contribute

Compare Databases with SQL Effects Clarity
 
 VB6 Implementation of XML Parser

Posted on
2/11/2004
Author:
Brian Yule
Email:
Not Shown
Applies To OS:
NT, 9x, 2000
Product:
5, 6



By Brian Yule (byule at PembrokeTechnology.com)
Download the project (40 kb)

That's true, there is MSXML. But sometimes life calls for in-code solutions. Sometimes you can't wait for MS to fix bugs. Sometimes you need something you can control. That's where this project comes in. It provides an XML parser with a interface similar to that of MSXML. The code is light-weight and very quick.

Provided below (it is also in the download) is the code to load any given XML file into the TreeView control. You can see how remarkably easy the XML parser is to use.

The code comes as code group containing 2 projects. The 1st one is the XML Parser implementation itself. It is implemented as an ActiveX DLL. The second project is the test project that drives the XML Parser and loads a file into the TreeView control. To get started, simply double-click the g.vbg file. Also included is a sample XML file.

Add the following to a Form

Option Explicit

Private Sub btnLoadXmlFile_Click()
    Dim oDoc As MYXMLDOM.XMLDOC
    
    'first pick the file
    With cd
        .Filter = "XML Files (*.xml) |*.xml"
        .ShowOpen
    
        If Len(.FileName) = 0 Then Exit Sub
    End With
    
    
    Set oDoc = New MYXMLDOM.XMLDOC
    With oDoc
        .loadXML (load(cd.FileName))
    End With
    
    'load the file into the tree
    LoadDocIntoTree oDoc
    
    Set oDoc = Nothing
End Sub

Private Sub LoadDocIntoTree(oDoc As MYXMLDOM.XMLDOC)
    Dim oTvNode As MSComctlLib.Node
    Dim oXmlNode As MYXMLDOM.XMLNODE
    Dim x As Long
    
    tv.Nodes.Clear

    With oDoc
        'grab the top node - there can only be one
        If .HasChildNodes Then
            For x = 0 To .ChildNodes.Count - 1
                Set oXmlNode = .ChildNodes(x)
                
                If oXmlNode.NodeType <> NODE_COMMENT And oXmlNode.NodeType <> NODE_PROCESSING_INSTRUCTION Then
                
                    Set oTvNode = tv.Nodes.Add(, , NextKey(), oXmlNode.NodeName)
                    oTvNode.EnsureVisible
                    
                    If oXmlNode.HasChildNodes Then
                        LoadChildNodesIntoTree oXmlNode, oTvNode
                    End If
                End If
            
            Next
        End If
    End With
    
    
    'make sure the top node is visible
    If tv.Nodes.Count > 0 Then tv.Nodes(1).EnsureVisible
    
    Set oTvNode = Nothing
    Set oXmlNode = Nothing
End Sub

Private Sub LoadChildNodesIntoTree(oXmlNode As XMLNODE, ParentTvNode As MSComctlLib.Node)
    Dim x As Long
    Dim oChildXmlNode As XMLNODE
    Dim oChildTvNode As MSComctlLib.Node
    
    With oXmlNode
        If .HasChildNodes Then
            For x = 0 To .ChildNodes.Count - 1
                Set oChildXmlNode = .ChildNodes(x)
                
                If oChildXmlNode.NodeType <> NODE_COMMENT And oChildXmlNode.NodeType <> NODE_PROCESSING_INSTRUCTION Then
                    
                    Set oChildTvNode = tv.Nodes.Add(ParentTvNode.Key, tvwChild, NextKey(), oChildXmlNode.NodeName)
                    oChildTvNode.EnsureVisible
                    
                    If oChildXmlNode.HasChildNodes Then
                        LoadChildNodesIntoTree oChildXmlNode, oChildTvNode
                    End If
                End If
                
                Set oChildXmlNode = Nothing
                Set oChildTvNode = Nothing
            Next
        End If
    End With    
End Sub

'HELPER FUNCTIONS
Private Function load(ByVal FileName As String) As String
    Dim xmlStr As String, xmlLine As String
    Dim freeFileNo As Integer
    freeFileNo = FreeFile
    Open FileName For Input As #freeFileNo
        If Not EOF(1) Then
            Do While Not EOF(freeFileNo)
                Input #freeFileNo, xmlLine
                xmlStr = xmlStr & " " & xmlLine
            Loop
        End If
    Close #freeFileNo
    load = xmlStr
End Function

Private Function NextKey() As String
    Static KeyCount As Integer
    
    KeyCount = KeyCount + 1
    
    '"x" is just a dummy letter
    'it is not needed here, just my way of doing stuff
    NextKey = "x" & KeyCount
    
End Function
Download the project (40 kb)





Add Your Comment  

Name: Email Address: all fields optional
Notify me via email when someone responds to this message (valid email required).

Enter the word:
 



Comments
#1. By Zele. Posted on 9/4/2006 2:46:53 PM
Thank you!

#2. By You're Kidding. Posted on 10/19/2006 10:21:57 PM
Don't use this library on anything other than the smallest XML files. It is extrmely slow. The parsing code copies VB strings excessively. With a 47K XML file andusing a 1.1GHz CPU, the code took 11 seconds to load the file (no parsing), and then forever to parse it. Literally forever; I was running in the VB IDE and I couldn't wait any longer.

Just for kicks--I would never use this code in my own project--I made some changes to see if I could make the library work on the 47K file. I improved the file reading code by adding some blocking of the input file reading code to avoid some of the performance hit of doing many concat operations. Then I changed all the "left()", "right()" and "trim()" functions to "left$()", "right$()" and "trim$()", and thus return strings and not variants. I also changed many places where strings were being passed explicitly with "ByVal" (for no reason) to ByRef. (It appears that Brian doesn't know what ByRef and ByVal do and the performance impact of using ByVal when you don't need it.)

My changes reduced the file read time by a factor of 4, but unfortunately, nothing other than a total rewrite will help the parsing code. The algorithm is bad, especially given that VB is slow at copying strings.

#3. By Locks up and dies. Posted on 10/23/2006 12:52:28 AM
Should have known not to trust code posted on a web page that can't even display properly!
This probably works for extremely small files (<1k) - but for anything substantial it will kill your machine.

#4. By rob. Posted on 8/29/2007 2:52:00 PM
#2 and #3 - I guess you two are just to smart for this world!!

#5. By Govard. Posted on 12/5/2007 10:38:20 PM
Well, I cant agree more.

#6. By Mohammad. Posted on 12/20/2007 11:13:45 PM
hi,
thanks for this information.

#7. By Anonymous. Posted on 2/16/2008 2:45:54 AM
If any one think that this code becomes slower. Then he should also post a better code.

#8. By Mark Pearl. Posted on 4/24/2008 10:06:17 AM
Very nice code... thank you for making it available.