Although the Simple API for XML (SAX) can catch many events as it parses through a document, this application focuses on the most frequently used methods. In this example, the ContentHandlerImpl class implements all methods for IVBSAXContentHandler and IVBSAXErrorHandler interfaces, but code is added only to those methods that you want the application to be aware of, including documentLocator, startElement, endElement, characters, and endDocument for the ContentHandler, and fatalError for the ErrorHandler. As the reader passes through the document, it reports events in document order: documentLocator, followed by startDocument, startElement, characters, endElement, and endDocument.
The set IVBSAXContentHandler_documentLocator method is the first event thrown by the SAX reader when is passes through a document. This method receives a pointer to the IVBSAXLocator interface, which provides methods for returning the column number, line number, public ID, or system ID for a current document. Because this is the first method thrown, it is a good place to put initialization code.
In the following snippet, the Initialize procedure sets the TitleTrue flag, the flag that indicates if the element is within scope, to False. This procedure also sets the errorHappen flag to False. This flag is used to indicate that a fatal error has been thrown by the ErrorHandler and prevents the HandleError procedure in the form from overwriting the error message thrown by the ErrorHandler.
Private Property Set IVBSAXContentHandler_documentLocator(ByVal RHS As _
MSXML2.IVBSAXLocator)
Initialize
End Property
Private Sub Initialize()
errorHappen = False
TitleTrue = False
End Sub
The startElement event is thrown by the reader each time it encounters the "<" character of a new element. The startElement method receives the namespace URI for the element, the local name, and the qualified name of the element. Attributes for the element are sent as a separate object containing the type, URI, local name, and value of each attribute. These values can be accessed from the attributes object within the startElement method.
In this method, the first if clause sets the FilterTrue flag if the element name passed by the startElement event matches the element name specified as the filter criteria. When FilterTrue is True, the second if clause invokes the startElement method from the oContentHandler object, which holds a reference pointing to oWriter, the MXXMLWriter object created in the form. This pushes the data passed by the startElement method to the oWriter object.
Private Sub IVBSAXContentHandler_startElement(strNamespaceURI As String, _
strLocalName As String, _
strQName As String, _
ByVal oAttributes As _
MSXML2.IVBSAXAttributes)
If strLocalName = FilterCriteria Then
FilterTrue = True
End If
If FilterTrue Then
oContentHandler.startElement strNamespaceURI, strLocalName, _
strQName, oAttributes
End If
End Sub
The characters method receives the character content between the opening and closing tags of an element. For this example, the characters method contains code that pushes character data to the writer only when the FilterTrue flag is set to True.
Private Sub IVBSAXContentHandler_characters(strChars As String)
If FilterTrue Then
oContentHandler.characters strChars
End If
End Sub
SAX often throws events in pairs, modeling the structure of the XML document. For example, a startDocument event has a corresponding endDocument event and a startElement event has a corresponding endElement event. For the endElement method, the first if clause pushes the content received by the endElement method to the writer when the FilterTrue flag is True. The second if clause sets the FilterCriteria flag to False when the value passed by the endElement method matches the filter criteria. This indicates that the element is no longer in scope.
Private Sub IVBSAXContentHandler_endElement(strNamespaceURI As String, _
strLocalName As String, _
strQName As String)
If FilterTrue Then
oContentHandler.endElement strNamespaceURI, strLocalName, _
strQName
End If
If strLocalName = FilterCriteria Then
FilterTrue = False
End If
End Sub
Finally, code is added to the fatalError method to capture any errors thrown by the reader during parsing. If a fatal error is received, the error message is displayed in the Text1 box. The errorHappen flag is set to True, preventing the HandlerError routine in the form from overwriting the fatalError error message.
Private Sub IVBSAXErrorHandler_fatalError(ByVal oLocator As _
MSXML2.IVBSAXLocator, _
strErrorMessage As String,_
ByVal nErrorCode As Long)
Form1.Text1.Text = strErrorMessage & nErrorCode
errorHappen = True
End Sub
Run the Application | IMXWriter Interface | MXXMLWriter CoClass | ISAXContentHandler Interface | ISAXErrorHandler Interface