SAXErrorHandling C-C++ example

 

In this topic, you will create the headers and source files for SAXErrorHandling application.

One of the most important activities when creating a Simple API for XML (SAX2) application is to implement handler classes. This example implements the following handler classes:

  • ContentHandler, which is derived from the ISAXContentHandler interface. The ContentHandler is implemented in MyContent.cpp. The ISAXContentHandler interface receives notification of the logical content of a document. This is the main interface implemented by most SAX applications.

  • SAXErrorHandlerImpl, which is derived from the ISAXErrorHandler interface. The SAXErrorHandlerImpl is implemented in SAXErrorHandlerImpl.cpp. The ISAXErrorHandler interface provides the basic interface for handling parsing errors.

In addition to implementing handler classes, this application implements_tmain in SAXErrorHandling.cpp. The main program does the following:

  1. Creates an instance of ISAXXMLReader (reader).

  2. Creates instances of ContentHandler and SAXErrorHandlerImpl and registers these handlers with the reader object.

  3. Sets the source for the XML document.

  4. Starts the parsing process.

When you created your SAXErrorHandling project, Microsoft Visual Studio created the file SAXErrorHandling.cpp. Modify SAXErrorHandling.cpp so that it contains the following code:

// SaxJumpStart.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "MyContent.h"
#include "SAXErrorHandlerImpl.h"

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc<2) {
        printf("\nTo run, enter\n\tSaxJumpStart file:///drive:/path/file.xml\n\n");
        return 0;	// Need URL to read
    }

    CoInitialize(NULL); 
    ISAXXMLReader* pRdr = NULL;

    HRESULT hr = CoCreateInstance(
                                __uuidof(SAXXMLReader60), 
                                NULL, 
                                CLSCTX_ALL, 
                                __uuidof(ISAXXMLReader), 
                                (void **)&pRdr);

    if(!FAILED(hr)) 
    {
        MyContent * pMc = new MyContent();
        hr = pRdr->putContentHandler(pMc);

        // Set error handler
        SAXErrorHandlerImpl * pEc = new SAXErrorHandlerImpl();
        hr = pRdr->putErrorHandler(pEc);

        printf("\nParsing document: %S\n", argv[1]);
        
        hr = pRdr->parseURL(argv[1]);
        printf("\nParse result code: %08x\n\n",hr);
    
        pRdr->Release();
    }
    else 
    {
        printf("\nError %08X\n\n", hr);
    }

    CoUninitialize();
    return 0;
}

Microsoft Visual Studio also created stdafx.h. Modify stdafx.h so that it contains the following code:

You are now ready to create the rest of the files that comprise the application. Create each file in Visual Studio, copy the code, and paste it into the file.

// MyContent.cpp: implementation of the MyContent class. 
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MyContent.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

MyContent::MyContent()
{
    idnt = 0;
}

MyContent::~MyContent()
{

}

HRESULT STDMETHODCALLTYPE MyContent::startElement( 
            /* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri,
            /* [in] */ int cchNamespaceUri,
            /* [in] */ const wchar_t __RPC_FAR *pwchLocalName,
            /* [in] */ int cchLocalName,
            /* [in] */ const wchar_t __RPC_FAR *pwchRawName,
            /* [in] */ int cchRawName,
            /* [in] */ ISAXAttributes __RPC_FAR *pAttributes)
{
    prt(L"<%s", pwchLocalName, cchLocalName);
    int lAttr;
    pAttributes->getLength(&lAttr);
    for(int i=0; i<lAttr; i++)
    {
        const wchar_t * ln;
        const wchar_t * vl;
        int lnl, vll;

        pAttributes->getLocalName(i,&ln,&lnl); 
        prt(L" %s=", ln, lnl);
        pAttributes->getValue(i,&vl,&vll);
        prt(L"\"%s\"", vl, vll);
    }
    printf(">"); 



    return S_OK;
}
        
HRESULT STDMETHODCALLTYPE MyContent::characters( 
            /* [in] */ const wchar_t __RPC_FAR *pwchChars,
            /* [in] */ int cchChars)
{
    prt(L"%s", pwchChars, cchChars); 
    return S_OK;
}
        
HRESULT STDMETHODCALLTYPE MyContent::endElement( 
            /* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri,
            /* [in] */ int cchNamespaceUri,
            /* [in] */ const wchar_t __RPC_FAR *pwchLocalName,
            /* [in] */ int cchLocalName,
            /* [in] */ const wchar_t __RPC_FAR *pwchRawName,
            /* [in] */ int cchRawName)
{
    prt(L"</%s>",pwchLocalName,cchLocalName); 
    return S_OK;
}

HRESULT STDMETHODCALLTYPE MyContent::startDocument()
{
    printf("<?xml version=\"1.0\" ?>");
    return S_OK;
}
        
void MyContent::prt(
            /* [in] */ const wchar_t * pwchFmt,
            /* [in] */ const wchar_t __RPC_FAR *pwchVal,
            /* [in] */ int cchVal)
{
    static wchar_t val[1000];
    cchVal = cchVal>999 ? 999 : cchVal;
    wcsncpy_s( val, pwchVal, cchVal );
    val[cchVal] = 0;
    wprintf(pwchFmt,val);
}

// SAXContentHandlerImpl.cpp: implementation of the SAXContentHandlerImpl class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SAXContentHandlerImpl.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


SAXContentHandlerImpl::SAXContentHandlerImpl()
{
}

SAXContentHandlerImpl::~SAXContentHandlerImpl()
{
}



HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::putDocumentLocator( 
            /* [in] */ ISAXLocator __RPC_FAR *pLocator
            )
{
    return S_OK;
}
        
HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::startDocument()
{
    return S_OK;
}
        

        
HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::endDocument( void)
{
    return S_OK;
}
        
        
HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::startPrefixMapping( 
            /* [in] */ const wchar_t __RPC_FAR *pwchPrefix,
            /* [in] */ int cchPrefix,
            /* [in] */ const wchar_t __RPC_FAR *pwchUri,
            /* [in] */ int cchUri)
{
    return S_OK;
}
        
        
HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::endPrefixMapping( 
            /* [in] */ const wchar_t __RPC_FAR *pwchPrefix,
            /* [in] */ int cchPrefix)
{
    return S_OK;
}
        

        
HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::startElement( 
            /* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri,
            /* [in] */ int cchNamespaceUri,
            /* [in] */ const wchar_t __RPC_FAR *pwchLocalName,
            /* [in] */ int cchLocalName,
            /* [in] */ const wchar_t __RPC_FAR *pwchRawName,
            /* [in] */ int cchRawName,
            /* [in] */ ISAXAttributes __RPC_FAR *pAttributes)
{
    return S_OK;
}
        
       
HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::endElement( 
            /* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri,
            /* [in] */ int cchNamespaceUri,
            /* [in] */ const wchar_t __RPC_FAR *pwchLocalName,
            /* [in] */ int cchLocalName,
            /* [in] */ const wchar_t __RPC_FAR *pwchRawName,
            /* [in] */ int cchRawName)
{
    return S_OK;
}
        
HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::characters( 
            /* [in] */ const wchar_t __RPC_FAR *pwchChars,
            /* [in] */ int cchChars)
{
    return S_OK;
}
        

HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::ignorableWhitespace( 
            /* [in] */ const wchar_t __RPC_FAR *pwchChars,
            /* [in] */ int cchChars)
{
    return S_OK;
}
        

HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::processingInstruction( 
            /* [in] */ const wchar_t __RPC_FAR *pwchTarget,
            /* [in] */ int cchTarget,
            /* [in] */ const wchar_t __RPC_FAR *pwchData,
            /* [in] */ int cchData)
{
    return S_OK;
}
        
        
HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::skippedEntity( 
            /* [in] */ const wchar_t __RPC_FAR *pwchVal,
            /* [in] */ int cchVal)
{
    return S_OK;
}


long __stdcall SAXContentHandlerImpl::QueryInterface(const struct _GUID &riid,void ** ppvObject)
{
    return 0;
}

unsigned long __stdcall SAXContentHandlerImpl::AddRef()
{
    return 0;
}

unsigned long __stdcall SAXContentHandlerImpl::Release()
{
    return 0;
}

In the following listing, the code is added to the fatalError and error methods to capture any errors thrown by the reader during parsing.

// SAXErrorHandler.cpp: implementation of the SAXErrorHandler class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SAXErrorHandlerImpl.h"
#include <stdio.h>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

SAXErrorHandlerImpl::SAXErrorHandlerImpl()
{

}

SAXErrorHandlerImpl::~SAXErrorHandlerImpl()
{

}

HRESULT STDMETHODCALLTYPE SAXErrorHandlerImpl::error( 
            /* [in] */ ISAXLocator __RPC_FAR *pLocator,
            /* [in] */ const wchar_t * pwchErrorMessage,
            /* [in] */ HRESULT errCode)
{
    ReportError(pwchErrorMessage, errCode); 
    return S_OK;
}
        
HRESULT STDMETHODCALLTYPE SAXErrorHandlerImpl::fatalError( 
            /* [in] */ ISAXLocator __RPC_FAR *pLocator,
            /* [in] */ const wchar_t * pwchErrorMessage,
            /* [in] */ HRESULT errCode)
{
    ReportError(pwchErrorMessage, errCode); 
    return S_OK;
}
        
HRESULT STDMETHODCALLTYPE SAXErrorHandlerImpl::ignorableWarning( 
            /* [in] */ ISAXLocator __RPC_FAR *pLocator,
            /* [in] */ const wchar_t * pwchErrorMessage,
            /* [in] */ HRESULT errCode)
{
    return S_OK;
}

long __stdcall SAXErrorHandlerImpl::QueryInterface(const struct _GUID &,void ** )
{
    return 0;
}

unsigned long __stdcall SAXErrorHandlerImpl::AddRef()
{
    return 0;
}

unsigned long __stdcall SAXErrorHandlerImpl::Release()
{
    return 0;
}

void SAXErrorHandlerImpl::ReportError(
            /* [in] */ const wchar_t __RPC_FAR *pwchVal,
            /* [in] */ HRESULT errCode)
{
    int len = wcslen(pwchVal);
    static wchar_t val[1000];
    len = len>999 ? 999 : len;
    wcsncpy_s( val, pwchVal, len );
    val[len] = 0;
    wprintf(L"\nError Message:\n%s ",val);
}

To compile and run this example, follow the instructions in the Build and Run SAXErrorHandling C/C++ example.

Show: