Microsoft KB Archive/252514

From BetaArchive Wiki
Knowledge Base

How To Select a Single Node in an XML Document from a TreeView in Visual Basic

Article ID: 252514

Article Last Modified on 7/13/2004


  • Microsoft XML Parser 2.0
  • Microsoft XML Core Services 4.0
  • Microsoft XML Core Services 4.0
  • Microsoft Visual Basic 6.0 Enterprise Edition
  • Microsoft ActiveX Data Objects 2.1
  • Microsoft ActiveX Data Objects 2.5
  • Microsoft ActiveX Data Objects 2.6

This article was previously published under Q252514


One of the methods added to the IDOMNode object in the IXMLDOMNode interface in Microsoft Internet Explorer 5 (IE5) is the SelectSingleNode method. This method applies a specified pattern-matching operation to a node's context and returns the first matching node. This behavior is similar to the SelectNode method, which returns a list of matching nodes.


The following sample demonstrates one implementation of this method. This sample opens an ADO Recordset and saves the data to an XML Document file using the FileSystemObject. This XML file is subsequently opened, and a Visual Basic TreeView control is filled with its data. Subsequently, the SelectSingleNode method is implemented to select a single node in the XML Document based on an item chosen from the TreeView control.

If a newer version of MSXML has been installed in side-by-side mode, you must explicitly use the Globally Unique Identifiers (GUIDs) or ProgIDs for that version to run the sample code. For example, MSXML version 4.0 can only be installed in side-by-side mode. For additional information about the code changes that are required to run the sample code with the MSXML 4.0 parser, click the following article number to view the article in the Microsoft Knowledge Base:

305019 INFO: MSXML 4.0 Specific GUIDs and ProgIds

NOTE: The $ieq$ syntax is used here for pattern matching against a Node Element. However, the "@" syntax can be used for Attribute pattern matching.

  1. To run this sample, start a new Visual Basic Standard Exe project. Form1 is created by default.
  2. On the Project menu, under References, select the following items: Microsoft ActiveX Data Objects Library
    Microsoft XML, Version 1.0 or later
    Microsoft Scripting Runtime*
    • The FileSystemObject Object Model is contained in the Microsoft Scripting Runtime Library.

  3. From the Project menu, add a standard Module and copy the following code to create the appropriate variables needed in the project:

    Option Explicit
    Public cn As New adodb.Connection
    Public rs As New adodb.Recordset
    Public myI As Integer
    Public StrTmp As String
    Public Errs1 As Errors
    Public myFSO As New FileSystemObject
    Public myTxtStream As TextStream
    Public myfld As adodb.Field
    Public domdoc As New MSXML.DOMDocument
    To specify a specific version, use a declaration like the following, with the appropriate version in the ProgID:
    Public domdoc As New MSXML2.DOMDocument40
  4. Draw the following controls on Form1 and set their Properties as listed below:

    Control             Name            Caption
    Command Button          cmdOpenRS               Open ADO Recordset
    Command Button          cmdSaveRSasXML          Save RS as XML using FSO
    Command Button          cmdPopulateTview        Populate TreeView
    Command Button          cmdExit                 Exit
    Label               lblNodeSelected         Node Selected:
    Text BoX                txtNodeSelected
    TreeView Control*       xtvFSO
    *The TreeView Control is part of the Windows Common Controls.
    Therefore, you'll want to check this off in your Project-Components list.
  5. Copy the following code into the General Declarations section of the code window:NOTE: Replace your Server Name, User ID, and Password information in the Connection String.

    Option Explicit
    Private Sub cmdOpenRS_Click()
    On Error GoTo AdoError
    Screen.MousePointer = vbHourglass
    'Check to be sure the connection is not already opened:
    If cn.State = 1 Then
        Set cn = Nothing
    End If
    cn.Open "driver={SQL Server};Server=YourServer; " & _
    'Check to be sure a Recordset is not already opened:
    If rs.State = 1 Then
        Set rs = Nothing
    End If
    With rs
        .CursorLocation = adUseClient
        .CursorType = adOpenStatic
        .LockType = adLockOptimistic
        .CacheSize = 50
        .Source = "Select CustomerID, " & _
        "CompanyName, ContactName, Region from Customers"
        .ActiveConnection = cn
    End With
    'txtFsoRecordCount.Text = rs.RecordCount
    MsgBox "There are " & rs.RecordCount & " Records in RS"
    Screen.MousePointer = vbNormal
    Exit Sub
    Dim errLoop As Error
    Dim strError As String
    myI = 1
    StrTmp = StrTmp & vbCrLf & "VB Error # " & Str(Err.Number)
    StrTmp = StrTmp & vbCrLf & "   Generated by " & Err.Source
    StrTmp = StrTmp & vbCrLf & "   Description  " & Err.Description
    ' Display Error Information for each Error object.
    Set Errs1 = cn.Errors
    For Each errLoop In Errs1
        With errLoop
            StrTmp = StrTmp & vbCrLf & "Error #" & myI & ":"
            StrTmp = StrTmp & vbCrLf & "   ADO Error   #" & .Number
            StrTmp = StrTmp & vbCrLf & "   Description  " & .Description
            StrTmp = StrTmp & vbCrLf & "   Source       " & .Source
            myI = myI + 1
        End With
    MsgBox StrTmp
    End Sub
    Private Sub cmdExit_Click()
    If cn.State = 1 Then
        Set cn = Nothing
    End If
    If rs.State = 1 Then
        Set rs = Nothing
    End If
    Unload Me
    End Sub
    Private Sub cmdSaveRSasXML_Click()
    Screen.MousePointer = vbHourglass
    'If the file already exists, first Kill it.
    'then create it:
    'If it does not already exist, simply create it:
    On Error GoTo mdkNoSeeEm
    Const mdkNoSeeEm = 53 'File Not Found
    Kill "Customers.xml"
    'Create a Text file using the FileSystemObject:
    Set myTxtStream = myFSO.CreateTextFile(App.Path & "\Customers.xml", 
    True, True)
    'Write data to the Text File to compile
    'the XML Document using the TextStream:
    myTxtStream.WriteLine "<?xml version=""1.0"" standalone=""yes""?>"
    myTxtStream.WriteLine "<Customers>"
        Do While Not rs.EOF
    myTxtStream.WriteLine "<Customer>"
    myTxtStream.WriteLine "<CustomerID>" & 
    ReplaceEntXMLSpecChar(rs.Fields("CustomerID") & "", "&", "amp;") & 
    myTxtStream.WriteLine "<CompanyName>" & 
    ReplaceEntXMLSpecChar(rs.Fields("CompanyName") & "", "&", "amp;") & 
    myTxtStream.WriteLine "<ContactName>" & 
    ReplaceEntXMLSpecChar(rs.Fields("ContactName") & "", "&", "amp;") & 
    myTxtStream.WriteLine "<Region>" & 
    ReplaceEntXMLSpecChar(rs.Fields("Region") & "", "&", "amp;") & 
    myTxtStream.WriteLine "</Customer>"
    myTxtStream.WriteLine "</Customers>"
    Screen.MousePointer = vbNormal
    Exit Sub
        If Err.Number = mdkNoSeeEm Then
            Resume Next
        End If
    Screen.MousePointer = vbNormal
    End Sub
    Private Function ReplaceEntXMLSpecChar(ByVal strSource As String, ByVal 
    strSearchFor As String, ByVal strReplace As String) As String
        Dim lngPointer As Long, strNew As String
        lngPointer = InStr(strSource, strSearchFor)
        If lngPointer = 0 Then
            ReplaceEntXMLSpecChar = strSource
            strNew = Left$(strSource, lngPointer - 1) & strReplace & 
    Mid(strSource, lngPointer + 1, Len(strSource))
            ReplaceEntXMLSpecChar = strNew
        End If
    End Function
    Private Sub cmdPopulateTview_Click()
    On Error GoTo MyXMLPerr
    'Fill The TreeView with data from the XML Document:
    With domdoc
        .async = False
        .Load App.Path & "\customers.xml"
    End With
    If domdoc.readyState = 4 Then
        AddNode domdoc.documentElement
    End If
    Exit Sub
        MsgBox domdoc.parseError.reason & vbCrLf & " Line Number In 
    Document: " & domdoc.parseError.Line & vbCrLf & 
    End Sub
    Private Sub xtvFSO_DblClick()
    Dim mytempTVnode As String
    Dim SelectedNode As IXMLDOMNode
    mytempTVnode = xtvFSO.SelectedItem
    Set SelectedNode = 
    D $ieq$ '" & mytempTVnode & "']")
    txtNodeSelected.Text = SelectedNode.childNodes(2).Text
    End Sub<BR/>
    Private Sub AddNode(ByRef myNode As IXMLDOMNode, Optional ByRef TreeNode As Node)
    Dim tvcusterrNode As Node
    Dim tvcusterrNodeList As IXMLDOMNodeList
    Dim i As Long
        If TreeNode Is Nothing Then
            Set tvcusterrNode = xtvFSO.Nodes.Add
            Set tvcusterrNode = xtvFSO.Nodes.Add(TreeNode, tvwChild)
        End If
        tvcusterrNode.Expanded = True
        tvcusterrNode.Text = myNode.nodeName
        If tvcusterrNode.Text = "#text" Then
               tvcusterrNode.Text = myNode.nodeTypedValue
               tvcusterrNode.Text = "<" & tvcusterrNode.Text & ">"
        End If
        Set tvcusterrNodeList = myNode.childNodes
        For i = 0 To tvcusterrNodeList.length - 1
            AddNode tvcusterrNodeList.Item(i), tvcusterrNode
    End Sub
  6. Run the project.
  7. Click the Open ADO Recordset Commandbutton to open a Connection and Recordset, displaying the RecordCount Property.
  8. Click the Save RS as XML Commandbutton to create the XML Document file.
  9. Click the Populate TreeView Commandbutton to fill the TreeView control.
  10. Double-click on any Customer ID in the TreeView, and note that the Contact Name for that Customer ID is displayed in the Text Box.

Keywords: kbhowto KB252514