受篇幅所限,我只能在本文简单的讨论一下SAX是如何工作的,如果你对SAX感兴趣,我建议你看看我们以前的一篇文章《XML基础教程:掌握SAX 》一文。简单的说,SAX(XML的简单API,即Simple API for XML)是一种连续的push解析器,SAX解析器把XML文档中的元素按照先后顺序依次推到它的主应用程序中。SAX最初是用来作为Java的解析器的,随后用于各种各样的其它语言,包括微软公司的COM实现。最为一种解析器,SAX相对于DOM的一个优势就是处理大文档以及查询文档中某段特定信息。当然,SAX要比DOM复杂,它要求你跟踪SAX正在处理的内容信息以便知道解析器处于文档中的哪个部分。
'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)