Microsoft KB Archive/252514

From BetaArchive Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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



APPLIES TO

  • 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

SUMMARY

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.

MORE INFORMATION

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
        cn.Close
        Set cn = Nothing
    End If
    
    cn.Open "driver={SQL Server};Server=YourServer; " & _
    "uid=YourUID;pwd=YourPWD;database=Northwind"
    
    'Check to be sure a Recordset is not already opened:
    If rs.State = 1 Then
        rs.Close
        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
        .Open
    End With
    
    rs.MoveLast
    rs.MoveFirst
    
    'txtFsoRecordCount.Text = rs.RecordCount
    MsgBox "There are " & rs.RecordCount & " Records in RS"
    
    Screen.MousePointer = vbNormal
    
    Exit Sub
    
    AdoError:
    
    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
    Next
    
    MsgBox StrTmp
    
    End Sub
    
    Private Sub cmdExit_Click()
    If cn.State = 1 Then
        cn.Close
        Set cn = Nothing
    End If
    
    If rs.State = 1 Then
        rs.Close
        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>"
    rs.MoveFirst
    
        Do While Not rs.EOF
    myTxtStream.WriteLine "<Customer>"
    myTxtStream.WriteLine "<CustomerID>" & 
    
    ReplaceEntXMLSpecChar(rs.Fields("CustomerID") & "", "&", "amp;") & 
    
    "</CustomerID>"
    myTxtStream.WriteLine "<CompanyName>" & 
    
    ReplaceEntXMLSpecChar(rs.Fields("CompanyName") & "", "&", "amp;") & 
    
    "</CompanyName>"
    myTxtStream.WriteLine "<ContactName>" & 
    
    ReplaceEntXMLSpecChar(rs.Fields("ContactName") & "", "&", "amp;") & 
    
    "</ContactName>"
    myTxtStream.WriteLine "<Region>" & 
    
    ReplaceEntXMLSpecChar(rs.Fields("Region") & "", "&", "amp;") & 
    
    "</Region>"
    myTxtStream.WriteLine "</Customer>"
    rs.MoveNext
    Loop
    rs.MoveFirst
    
    myTxtStream.WriteLine "</Customers>"
    
    myTxtStream.Close
    
    Screen.MousePointer = vbNormal
    
    Exit Sub
    
    mdkNoSeeEm:
        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
        Else
            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
        xtvFSO.Nodes.Clear
        AddNode domdoc.documentElement
    End If
    
    Exit Sub
    
    MyXMLPerr:
        MsgBox domdoc.parseError.reason & vbCrLf & " Line Number In 
    
    Document: " & domdoc.parseError.Line & vbCrLf & 
    
    domdoc.parseError.srcText
    End Sub
    
    Private Sub xtvFSO_DblClick()
    
    Dim mytempTVnode As String
    Dim SelectedNode As IXMLDOMNode
    
    mytempTVnode = xtvFSO.SelectedItem
    Set SelectedNode = 
    
    domdoc.documentElement.SelectSingleNode("//Customers/Customer[CustomerI
    
    D $ieq$ '" & mytempTVnode & "']")
    txtNodeSelected.Text = SelectedNode.childNodes(2).Text
    End Sub<BR/>
    <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
        Else
            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
        Else
               tvcusterrNode.Text = "<" & tvcusterrNode.Text & ">"
        End If
    
        Set tvcusterrNodeList = myNode.childNodes
        For i = 0 To tvcusterrNodeList.length - 1
            AddNode tvcusterrNodeList.Item(i), tvcusterrNode
        Next
    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