Listing A – cSaxReader.cls
Option Explicit
 
'implement the content handler and error handler interfaces here
Implements MSXML2.IVBSAXContentHandler
Implements MSXML2.IVBSAXErrorHandler
 
Private m_book As cBook 'New book
Private m_colBooks As cBooksCollection  'books collection
Private m_oSaxReader As MSXML2.SAXXMLReader 'SAX reader
Private m_currentElement As String  'last element name handed off from reader
Private m_blParsingABook As Boolean 'true if we're inside a book element
 
Public Sub LoadBooks(strFile As String)
    On Error GoTo err_LoadBooks
    'SAXXMLReader throws errors for parse errors regardless of whether or not
    'we're handling errors in an IVBSAXErrorHandler implementation
   
    'parse a file from a URL
    m_oSaxReader.parseURL strFile
    Exit Sub
   
err_LoadBooks:
    MsgBox "Unable to load from file, book list may be incomplete."
    Exit Sub
   
End Sub
 
Public Function GetBookList() As cBooksCollection
    'retrieve the finished book list
    Set GetBookList = m_colBooks
End Function
 
Private Sub Class_Initialize()
    'set up the SAX reader
    Set m_oSaxReader = New MSXML2.SAXXMLReader
    'pass a reference to this object to use as the content handler...
    Set m_oSaxReader.contentHandler = Me
    'and error handler objects
    Set m_oSaxReader.errorHandler = Me
       
End Sub
 
Private Sub Class_Terminate()
    Set m_oSaxReader = Nothing
    Set m_colBooks = Nothing
    Set m_book = Nothing
   
End Sub
 
Private Sub IVBSAXContentHandler_characters(strChars As String)
    'skip the element if we aren't parsing a book (inside a book element)
    'easy way to skip whitespace
    If m_blParsingABook Then
        'check the last element name sent to startElement to determine
        'what to do with the data we just received
       Select Case m_currentElement
            Case "title"
                m_book.Title = strChars
            Case "author"
                m_book.Author = strChars
            Case "price"
                m_book.Price = CCur(strChars)
            Case "publish_date"
                m_book.Pub_Date = CDate(strChars)
            Case "genre"
                m_book.Genre = strChars
            Case "description"
                m_book.Description = strChars
        End Select
    End If
   
End Sub
 
Private Property Set IVBSAXContentHandler_documentLocator(ByVal RHS As MSXML2.IVBSAXLocator)
 
End Property
 
Private Sub IVBSAXContentHandler_endDocument()
 
End Sub
 
Private Sub IVBSAXContentHandler_endElement(strNamespaceURI As String, strLocalName As String, strQName As String)
    'if we just moved out of a book element, then create a new Book
    'object and reset the parsing flag.
    If strLocalName = "book" Then
        m_colBooks.AddBook m_book
        m_blParsingABook = False
    End If
    'discard the current element name
    m_currentElement = ""
   
End Sub
 
Private Sub IVBSAXContentHandler_endPrefixMapping(strPrefix As String)
 
End Sub
 
Private Sub IVBSAXContentHandler_ignorableWhitespace(strChars As String)
 
End Sub
 
Private Sub IVBSAXContentHandler_processingInstruction(strTarget As String, strData As String)
 
End Sub
 
Private Sub IVBSAXContentHandler_skippedEntity(strName As String)
 
End Sub
 
Private Sub IVBSAXContentHandler_startDocument()
    'create a new collection to hold the contents of a new document
    Set m_colBooks = New cBooksCollection
   
End Sub
 
Private Sub IVBSAXContentHandler_startElement(strNamespaceURI As String, strLocalName As String, strQName As String, ByVal oAttributes As MSXML2.IVBSAXAttributes)
    'preserve the name of the element we just entered
    m_currentElement = strLocalName
   
    'if this element is a book element then create a new book object
    'and set it's ID property, then set the parsing flag so that the
    'characters method will handle the child nodes of this book
    If strLocalName = "book" Then
        Set m_book = New cBook
        m_book.ID = oAttributes.getValueFromName("", "id")
        m_blParsingABook = True
    End If
   
End Sub
 
Private Sub IVBSAXContentHandler_startPrefixMapping(strPrefix As String, strURI As String)
 
End Sub
 
Private Sub IVBSAXErrorHandler_error(ByVal oLocator As MSXML2.IVBSAXLocator, strErrorMessage As String, ByVal nErrorCode As Long)
 
End Sub
 
Private Sub IVBSAXErrorHandler_fatalError(ByVal oLocator As MSXML2.IVBSAXLocator, strErrorMessage As String, ByVal nErrorCode As Long)
    'a fatal error occurred, note that the reader will also raise an error after this
    'routine exits
    Dim strMsg As String
    'The oLocator object contains context information
    'such as line and column numbers for the error
    strMsg = strErrorMessage & vbCrLf & "Line: " & oLocator.lineNumber & " Column: " & oLocator.columnNumber
    MsgBox "Parse failed: " & strMsg
End Sub
 
Private Sub IVBSAXErrorHandler_ignorableWarning(ByVal oLocator As MSXML2.IVBSAXLocator, strErrorMessage As String, ByVal nErrorCode As Long)
 
End Sub