Manually Building an XML Document with MXXMLWriter

MSXML 5.0 SDK

Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - SAX2 Developer's Guide

Manually Building an XML Document with MXXMLWriter

Using MXXMLWriter, you can build an XML document by manually calling methods of the Simple API for XML (SAX2) handlers. This section demonstrates how you can use type casting to get the interfaces that MXXMLWriter implements and how you can manually make calls to the methods of these interfaces to build an XML document. In this case, the application emulates SAXXMLReader by manually invoking the methods of the various handler interfaces, including IVBSAXContentHandler, IVBSAXDTDHandler, IVBSAXDeclHandler, IVBSAXErrorHandler, and IVBSAXLexicalHandler. In this portion of the sample MXXMLWriter application, SAXXMLReader is not used.

On its own, the IMXXMLWriter interface does not provide the handler methods required to manually construct an XML document. However, you can type cast MXXMLWriter to the required handler interfaces, which provides all the methods and properties to MXXMLWriter.

As you can see in the following sample application code, clicking the Try Demo button results in the application declaring the handler interface variables and then setting these handlers to the wrt object. This makes it possible for the wrt object to use any of the methods or properties of the declared handler interfaces.

Private Sub CommandTryDemo_Click()
    ' We need these variables for typecasting the writer.
    Dim cnth As IVBSAXContentHandler
    Dim dtdh As IVBSAXDTDHandler
    Dim lexh As IVBSAXLexicalHandler
    Dim dech As IVBSAXDeclHandler
    Dim errh As IVBSAXErrorHandler    

    ' This is just a helper.
    Dim atrs As New SAXAttributes50
    
    ' Set them all to writer. Writer implements all these interfaces.
    Set cnth = wrt
    Set dtdh = wrt
    Set lexh = wrt
    Set dech = wrt
    Set errh = wrt
    
    ' Set parameters, clean the scene.
    TextSource.Text = ""

In the sample MXXMLWriter application, the remainder of the CommandTryDemo_Click() subroutine constructs the document by calling various handler methods. For example, the following statement invokes the startDocument method of the IVBSAXContentHandler interface:

    cnth.startDocument

In a similar way, the following statement invokes the startDTD method of the IVBSAXLexicalHandler interface and passes the parameters to the wrt object:

    lexh.startDTD "MyDTD", "", "http://eureka.sample/mydtd.dtd"

Coupled with each call to a handler method, there is a call to the log subroutine, as follows:

    log "Content->startDocument"

The log subroutine, as shown in the following code, creates an entry in the left-hand text box for each method called.

Private Sub log(msg As String)
    TextSource.Text = TextSource.Text & vbCrLf & msg
End Sub

At the end of the CommandTryDemo_Click() subroutine, the application sets the textResults.text box to the output of the writer (as in the following code). Unless you flush the output buffer, it continues to aggregate data passed to it by the handlers.

TextResult.Text = wrt.output

Complete Code for the CommandTryDemo_Click() Subroutine

Private Sub CommandTryDemo_Click()
    'We need these variables for typecasting the writer.
    Dim cnth As IVBSAXContentHandler
    Dim dtdh As IVBSAXDTDHandler
    Dim lexh As IVBSAXLexicalHandler
    Dim dech As IVBSAXDeclHandler
    Dim errh As IVBSAXErrorHandler
    
    'This is just a helper.
    Dim atrs As New SAXAttributes50
    
    'Set handler variables to the writer so it implements the interfaces.
    Set cnth = wrt
    Set dtdh = wrt
    Set lexh = wrt
    Set dech = wrt
    Set errh = wrt
    
    ' Set parameters, clean the scene.
    TextSource.Text = ""
   
    ' Manually call necessary events to generate the XML file.
    log "Content->startDocument"
    cnth.startDocument
    log "Lexical->startDTD"
    lexh.startDTD "MyDTD", "", "http://eureka.sample/mydtd.dtd"
        log "Decl->elementDecl"
        dech.elementDecl "book", "title | descr"
        log "Decl->attributeDecl"
        dech.attributeDecl "book", "author", "CDATA", "#IMPLIED", ""
        log "Decl->attributeDecl"
        dech.attributeDecl "book", "ISBN", "CDATA", "#REQUIRED", _
          "000000000"
        log "Decl->attributeDecl"
        dech.attributeDecl "book", "cover", "(hard|soft)", "", "soft"
        log "Decl-elementDecl"
        dech.elementDecl "title", "(#PCDATA)"
        log "Decl-elementDecl"
        dech.elementDecl "descr", "(#PCDATA)"
    log "Lexical->endDTD"
    lexh.endDTD
    log "Content->startElement"
    atrs.addAttribute "", "", "cover", "", "hard"
    cnth.startElement "", "", "book", atrs
        log "Content->startElement"
        atrs.Clear
        cnth.startElement "", "", "title", atrs
        log "Content->characters"
        cnth.characters "On the Circular Problem of Quadratic Equations"
        log "Content->endElement"
        cnth.endElement "", "", "title"
    log "Content->endElement"
    cnth.endElement "", "", "book"
    
    TextResult.Text = wrt.output
End Sub

See Also

ISAXXMLReader Interface | IMXWriter Interface | ISAXContentHandler Interface | ISAXDeclHandler Interface | ISAXDTDHandler Interface | ISAXErrorHandler Interface | ISAXLexicalHandler Interface