Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Read XML Document, put items into a Collection

How-to

Read XML Document, put items into a Collection

by  PsychoCoder  Posted    (Edited  )
In the application I'm currently working on it involves communicating with a host application. If an error occurs, the host can send back one of about 60 error messages (depending). I needed a way to check the host response after entries. I didn't want to do an if loop through all 60 error messages so I came up with the idea of taking the error messages and putting them into a delimited file ( used "!" as my delimiter as some of the error messages had "," in them).

The earlier [link http://tek-tips.com/faqs.cfm?fid=6542]FAQ[/link] showed how I read the delimited file into an XML document, this one will show how to take the elements and put them into a collection for ease of use. First Ill do the actually Collection (it's actually 2 classes in one).

In the collection files first make sure to import the right namespaces:
Code:
Imports System
Imports System.Collections
Then start on the class
Code:
Public Class YourClass: [b]Implements IComparable[/b]
Make sure to add the bold text, its important within the class. Next you declare your Property variables (my xml document only has 2, you can have as many as your xml document has)
Code:
Private _sErrorTitle As String
Private _sDisplayText As String
Then add your ReadOnly Properties
Code:
Public ReadOnly Property ErrorTitle() As String
  Get
      Return _sErrorTitle
  End Get
End Property

Public ReadOnly Property DisplayText() As String
  Get
      Return _sDisplayText
  End Get
End Property
The properties can be names what you want them named (and if you're working with an XML document with more than 2 elements then make as many properties as you have elements). Next comes the instantiation and disposal of the class
Code:
Public Sub New(ByVal sErrTitle As String, ByVal sDisplayTxt As String)
   Me._sErrorTitle = sErrTitle
   Me._sDisplayText = sDisplayTxt
End Sub

Public Sub Dispose()
   Me.Dispose()
End Sub
Next, when you create a collection class that inherits IComparable you have to have a CompareTo function
Code:
Public Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
   'Check to see if obj is actually your collection class
   If Not (TypeOf obj Is YourCollection) Then
      'If not throw an exception
      Throw New ArgumentException
   End If

   Dim oObject As YourCollection = CType(obj, YourCollection)
   Dim cmpl As Integer = Me.ErrorTitle.CompareTo(oObject.YourCollection)
   If Not (cmpl = 0) Then
     Return cmpl
   End If
   Return Me.YourPropertyName.CompareTo(oOBject.YourPropertyName)
End Function

That is the function that implements IComparable, the second class uses the items in this class, but it inherits CollectionBase, doing this makes several methods available to collections not inheriting it. First name your class
Code:
Public Class YourClassCollection: Inherits CollectionBase
Then there are the standard instantiation/disposal methods
Code:
Public Sub New()
End Sub

Public Sub Dispose()
  Me.Dispose()
End Sub
First is the property, this is what you will be calling when you go to add the XML items into the collection
Code:
Default Public Property ErrorItems(ByVal idx As Integer) As FirstClassName
    Get
       'idx is the integer value of the index you are working with
       Return CType(Me.InnerList(idx), FirstClassName)
    End Get
    Set(ByVal value As FirstClassName)
      Me.InnerList(idx) = value
    End Set
End Property
Next are the methods that open up to you when you inherit from CollectionBase. First is the Add Method which adds the item to the collection
Code:
Public Sub Add(ByVal oObjectList As YourFirstClass)
  Me.InnerList.Add(oObjectList)
End Sub
Next is the method to remove an item from the class
Code:
Public Sub Remove(ByVal oObjectList As YourFirstClass)
    If Not Me.Contains(oObjectList) Then
       Exit Sub
    End If

    Dim iCount As Integer = 0
    While iCount < Me.InnerList.Count
    Dim oNewObjectList As YourFirstClass = CType(Me.InnerList(iCount), oObjectList)
    If oNewObjectList.CompareTo(oObjectList) = 0 Then
       Me.RemoveAt(iCount)
          Exit Sub
       End If
             System.Math.Min(System.Threading.Interlocked.Increment(iCount), iCount - 1)
   End While
End Sub
This function searches the collection looking for the requested item, if its found then it removes it from the collection.

The next method is the Contains method. This method is used in conjunction with the Remove method, when adding items to the collection I call this to see if the item already exists, if it does then I either call Removeto remove it then re add it, or I simply skip the item. The last method opened to you is the ability to turn the collection into an Array
Code:
Public Function ToArray() As YourFirstClass()
  Return CType(Me.InnerList.ToArray(GetType(YourFirstClass)), YourFirstClass())
End Function
Like I said, I made both class file in one. Now to read the XML doxument and add it to your new collection I used the following function. First create your 2 new class file in objects
Code:
Private oErrorList As FirstClass
Private oError As New ClassCollection

Then simply read the XML document and add to the collection. This function I have in a completely seperate class file, you can do it however you want, I personally prefer the use of Class files to seperate code.
Code:
Public Function GetList(ByVal sFile As String, ByVal sFileName As String, _
    ByVal sTagName As String) As ErrCollection
        'Check to make sure document exists
        If Not File.Exists(sFile.TrimEnd) Then 'Document doesnt exist
            'Write to error log
            oEvents.WriteToLog(sFileName.TrimEnd & ".xml file not found.", "", sFileName.TrimEnd & ".xml Not Found.")
            'Let the user knwo the problem
            MsgBox("The text file could not be found." & vbCrLf & _
            "Please contact your software support", MsgBoxStyle.Critical)
            'Exit the function
            Return Nothing
            Exit Function
        Else
            'Open the XML document
            xmlDoc.Load(sFile.TrimEnd)
            Try
                xmlDocNode = xmlDoc.GetElementsByTagName(sTagName.TrimEnd)
                'Loop through all the nodes in the xml document
                For Each xmlNewNode As Xml.XmlNode In xmlDocNode

                    'Create new collection object with the element values of the xml document
                    oErrorList = New ErrorList(xmlNewNode.Attributes("ErrorTitle").InnerText.TrimEnd, _
                                               xmlNewNode.Attributes("DisplayText").InnerText.TrimEnd)
                    'Check to see if it already exists in the Collection
                    If Not oError.Contains(oErrorList) Then 'Doesnt contain
                        'So add it
                        oError.Add(oErrorList)
                    Else    'Contains this element already
                        'So remove it
                        oError.Remove(oErrorList)
                    End If
                Next 'xmlNewNode
                GetList = oError
                Return GetList
            Catch ex As Exception   'An Exception occurred
                'Log the exception
                oEvents.WriteToLog(ex.Message, ex.StackTrace, "ConvertXMLToCollection Error")
                'Let the user know there was a problem
                MsgBox("The XML Document could not be converted." & vbCrLf & _
                            "Please contact your software support", MsgBoxStyle.Critical)
                'Exit the function
                Return Nothing
                Exit Function
            Finally 'Do this no matter what
                'Dispose of the objects
                oErrorList.Dispose()
                oError.Dispose()

                sFile = String.Empty
                sFileName = String.Empty
                sTagName = String.Empty
            End Try
        End If
    End Function
ErrorTitle and DisplayText are the name of my elements, you replace this with your own element names. oError and oErrorList are the names of my 2 objects, depending on what you name your classes replace these names with yours.

Now in the form's .vb file where I need to get the collection I do as follows,
first instantiate your objects
Code:
Private oError As New amaPNRError '(name of my collection)
Private oErrorList As ErrCollection '(Name of my collection)

Then use it like this
Code:
oErrorList = oError.GetList(Application.StartupPath & "\LoginErrorList.xml", "LoginErrorList", "ErrorList")
                For iCount As Integer = 0 To oErrorList.Count - 1
                    If Not ItHasErrors(oHost.LastResponse.Text, oErrorList.ErrorItems(iCount).ErrorTitle) = True Then   'No errors
                        _sErrMessage = EnumToText(9)
                        _bProcessComplete = True
                        _bHasErrors = False
                    Else
                        _sErrMessage = oErrorList.ErrorItems(iCount).ErrorTitle
                        _bProcessComplete = True
                        _bHasErrors = True
                        Exit Sub
                    End If
                Next
In this code there are things that are specific to my application, but it grabs the error list collection and I loop through it looking for anything that matches the response from the host, if one matches then I have an error so I need to set my error properties to true and exit the procedure.

I hope this helps someone in the future, I have ran my own tests and this approach seems to work faster then searching the document when I need to check for hours.
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top