Give this a try, but you will need to tailor it to your specific app.

/**
  * File: csCtkXmlEntityResolver.C
  * 
  * csCtkXmlEntityResolver provides a way for applications to redirect
references
  * to external entities. This implementation of the EntityResolver
interface honors the 
  * contract so defined.
  *
  * <p>Applications needing to implement customized handling for
external
  * entities must implement this interface and register their
implementation
  * by setting the entityResolver attribute of the DOMParser.</p>
  *
  * <p>The DOMParser will then allow the application to intercept any
  * external entities (including the external DTD subset and external
parameter
  * entities) before including them.</p>
  *
  * <p>Many DOM applications will not need to implement this interface,
but it
  * will be especially useful for applications that build XML documents
from
  * databases or other specialized input sources, or for applications
that use
  * URNs.</p>
  *
  * @see Parser#setEntityResolver
  * @see InputSource#InputSource
  * @see HandlerBase#HandlerBase
  * 
  * Author: D.Dantzler
  */

/*
 * $Id: csCtkXmlEntityResolver.C,v 1.1 2007/10/30 23:51:25 dcd9420 Exp $
 */
 
#include <iostream.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <csUtStr.h>
#include <xercesc/util/XMLString.hpp>
#include <csCtkXmlInputSource.h>  
#include <csCtkXmlEntityResolver.h>

csCtkXmlEntityResolver::csCtkXmlEntityResolver():_PublicId(NULL),_System
Id(NULL),_UseExternalDtdOrSchema(false)
{
}

csCtkXmlEntityResolver::csCtkXmlEntityResolver(const char* dtd, const
bool flag):_PublicId(NULL),_SystemId(NULL),_UseExternalDtdOrSchema(flag)

{
        if(dtd)
        {
                setSystemId((const char*)csUtStrDup(dtd));
        }
}

csCtkXmlEntityResolver::~csCtkXmlEntityResolver()
{
        if(_SystemId) free((void*)_SystemId);
        if(_PublicId) free((void*)_PublicId);
}

//-------------------------------------------------------------
// Check to see if this file exist 
//-------------------------------------------------------------
bool csCtkXmlEntityResolver::doesFileExist(  char* myFile )  
{
    struct stat s;
    
    //1st, is the filename valid, 2nd,does the path exist, and 3rd, is
it a file
    if( myFile && stat(myFile, &s) == 0 && S_ISREG(s.st_mode)  )
        return true ;
        
    return( false );
}

inline const char* csCtkXmlEntityResolver::getPublicId() const 
{
        return _PublicId;
}

inline const char* csCtkXmlEntityResolver::getSystemId() const 
{
        return _SystemId;
}

inline bool csCtkXmlEntityResolver::getUseExternalDtdOrSchema() const 
{
        return _UseExternalDtdOrSchema;
}

void csCtkXmlEntityResolver::setPublicId(const char* publicId) 
{
        _PublicId = _PublicId;
}

void csCtkXmlEntityResolver::setSystemId(const char* systemId) 
{
        _SystemId = systemId;
}

void csCtkXmlEntityResolver::setUseExternalDtdOrSchema(const bool flag) 
{
        _UseExternalDtdOrSchema = flag;
}

InputSource* csCtkXmlEntityResolver::resolveEntity(     const XMLCh*
const publicId, 
 
const XMLCh* const systemId)
{
        InputSource *inputSrc = NULL;

        //DEBUGGING - cout << "calling
csCtkXmlEntityResolver::resolveEntity" << endl;
        
        if(_UseExternalDtdOrSchema == true)
        {
                const char* extDtd = getSystemId();
                
                if(extDtd)
                {
                        //Use the external DTD passed into the Resolver
Entity to validate the Entities
                        //Regardless of the system Id of the XML file
being parsed
                        inputSrc = new csCtkXmlInputSource((const char
*const)extDtd);  
                }
                else//really want to bypass the default entity resolver,
so use a dummy dtd
                {
                        char *ddpsMpdDtd = getenv("DDPS_MPD_XML_DTD");
                        inputSrc = new csCtkXmlInputSource((const char
*const)ddpsMpdDtd); 
                }

                inputSrc->setIssueFatalErrorIfNotFound(true);
                
                /* Otherwise, assume the caller has set the option
'setDisableDefaultEntityResolution == true' 
                 * to 'NOT' perform default entity resolution. If the
resolveEntity method returns NULL the
             * parser will try to resolve the entity on its own.  When
this option
             * is set to true, the parser will not attempt to resolve
the entity
             * when the resolveEntity method returns NULL.
             * 
             * TODO - This scheme did not work and I have contacted
[email protected] user's group 10/07
             */
                
        }//if no external DTD/Schema was specified, then use the
systemId passed by the caller
        else if(systemId)
        {
                char *localSystemId = XMLString::transcode(systemId);
                
                //does this file exist locally
                if(doesFileExist(localSystemId) == true)
                {
                        //then use the local DTD
                        inputSrc = new csCtkXmlInputSource(systemId);  
                }
                else// if not, the parser will throw an Runtime
Exception indicating the DTD could not be opened
                {
                        //To possibly prevent a Runtime Exception, try
to locate the DTD 
                        char *ddpsMpdDtd = getenv("DDPS_MPD_XML_DTD");
                        char *ddpsMpd787Dtd =
getenv("DDPS_MPD787_XML_DTD");
                        
                        //based on the name of the systemId and a list
of DDPS DTD's, check for a match
                        if( csUtStrCaseStr(ddpsMpdDtd, localSystemId))
                        {
                                inputSrc = new
csCtkXmlInputSource((const char *const)ddpsMpdDtd);  
                        }
                        else if(csUtStrCaseStr(ddpsMpd787Dtd,
localSystemId))
                        {
                                inputSrc = new
csCtkXmlInputSource((const char *const)ddpsMpd787Dtd);  
                        }
                        else//Use the systemId passed by the caller to
let the Parser fail gracefully!! 
                        {
                                inputSrc = new
csCtkXmlInputSource(systemId); 
                        }
                }
                
                inputSrc->setIssueFatalErrorIfNotFound(true);
                XMLString::release(&localSystemId);
        }

        /** DEBUGGING
        if(inputSrc)
        {
                char *inSrcSysId =
XMLString::transcode(inputSrc->getSystemId());
                cout << "Input Source System Id ==> " << inSrcSysId <<
endl;
                XMLString::release(&inSrcSysId);
        }
        else
        {
                cout << "Input Source System Id ==> NULL" << endl;
        }
        */
        
        return inputSrc;

} 

/**
  * File: csCtkXmlInputSource.C
  * 
  * This implementation of the InputSource interface represents a single
input source for an XML entity.
  *
  * <p>This class encapsulates information about an input source in a
  * single object, which may include a public identifier or a system
  * identifier</p>
  *
  * <p>There are two places that the application will deliver this input
  * source to the parser: as the argument to the Parser::parse method,
or as
  * the return value of the EntityResolver::resolveEntity method.</p>
  *
  * <p>InputSource is never used directly, but is the base class for a
number
  * of derived classes for particular types of input sources.
Derivatives are
  * provided (in the framework/ directory) for URL input sources, memory
buffer
  * input sources, and so on.</p>
  *
  * <p>When it is time to parse the input described by an input source,
it
  * will be asked to create a binary stream for that source. That stream
will
  * be used to input the data of the source. The derived class provides
the
  * implementation of the makeStream() method, and provides a type of
stream
  * of the correct type for the input source it represents.
  *
  * <p>An InputSource object belongs to the application: the parser
never
  * modifies them in any way. They are always passed by const reference
so
  * the parser will make a copy of any input sources that it must keep
  * around beyond the call.</p>
  *
  * @see Parser#parse
  * @see EntityResolver#resolveEntity
  * 
  * Author: D.Dantzler
  */
  
 /*
 * $Id: csCtkXmlInputSource.C,v 1.1 2007/10/30 23:51:25 dcd9420 Exp $
 */
  
#include <iostream.h>  
#include <csCtkXmlInputSource.h>

        /** Default constructor */
csCtkXmlInputSource::csCtkXmlInputSource():_LocalFileIS(NULL)
{
}

    /** Constructor with a system identifier as XMLCh type.
      * @param systemId The system identifier (URI).
      * @param manager    Pointer to the memory manager to be used to
      *                   allocate objects.
      */
csCtkXmlInputSource::csCtkXmlInputSource(
                const XMLCh* const systemId,
                MemoryManager* const manager
    ):InputSource(systemId, manager)
{
        _LocalFileIS = new  LocalFileInputSource( systemId,manager);
}

    /** Constructor with a system and public identifiers
      * @param systemId The system identifier (URI).
      * @param publicId The public identifier as in the entity
definition.
      * @param manager    Pointer to the memory manager to be used to
      *                   allocate objects.
      */
csCtkXmlInputSource::csCtkXmlInputSource(
        const XMLCh* const   systemId,
        const XMLCh* const   publicId,
        MemoryManager* const manager 
    ):InputSource(systemId, publicId, manager)
{
        _LocalFileIS = new  LocalFileInputSource( systemId,manager);
}

    /** Constructor with a system identifier as string
      * @param systemId The system identifier (URI).
      * @param manager    Pointer to the memory manager to be used to
      *                   allocate objects.
      */
csCtkXmlInputSource::csCtkXmlInputSource(
                const char* const systemId,
                MemoryManager* const manager
        ):InputSource(systemId, manager)
{
        XMLCh* mySystemId = XMLString::transcode(systemId) ; 
        _LocalFileIS = new  LocalFileInputSource( mySystemId,manager);
        XMLString::release(&mySystemId);
}

    /** Constructor with a system and public identifiers. Both as string
      * @param systemId The system identifier (URI).
      * @param publicId The public identifier as in the entity
definition.
      * @param manager    Pointer to the memory manager to be used to
      *                   allocate objects.
      */
csCtkXmlInputSource::csCtkXmlInputSource(
        const char* const systemId,
        const char* const publicId,
        MemoryManager* const manager
    ):InputSource(systemId, publicId, manager)
{
        const XMLCh* const mySystemId = XMLString::transcode(systemId) ;

        _LocalFileIS = new  LocalFileInputSource( mySystemId,manager);
}

csCtkXmlInputSource::~csCtkXmlInputSource() 
{
        delete _LocalFileIS;
}

BinInputStream* csCtkXmlInputSource::makeStream() const 
{
        BinInputStream* bis = NULL;
        
        if(_LocalFileIS)
                bis = _LocalFileIS->makeStream();
                
        return bis;
}
-----Original Message-----
From: Balchandra Kemkar [mailto:[EMAIL PROTECTED] 
Sent: Thursday, January 31, 2008 4:36 AM
To: [email protected]
Subject: RE: DOMEntityResolver implementation


Yes I read that one.
In that it is mentioned that the function resolveEntity is a pure
virtual function.
And we need to implement it if we want to use the entity resolver.

So I just wanted to know if anyone has implemented this function.

Regards,
Balchandra 

-----Original Message-----
From: John Snelson [mailto:[EMAIL PROTECTED]
Sent: Thursday, January 31, 2008 5:38 PM
To: [email protected]
Subject: Re: DOMEntityResolver implementation

Hi Balchandra,

Have you read the documentation?

http://xerces.apache.org/xerces-c/apiDocs/classDOMEntityResolver.html

John

Balchandra Kemkar wrote:
> Hi All,
>  
> In xercesc we have an abstract class DOMEntityResolver that needs to 
> be implemented when we have to write our own entity resolver.
> Has anyone implemented this interface?
>  
> Any information in this regard would be a great help.
>  
> Thanks in Advance,
> Balchandra
> 


-- 
John Snelson, Oracle Corporation            http://snelson.org.uk/john
Berkeley DB XML:        http://www.oracle.com/database/berkeley-db/xml
XQilla:                                  http://xqilla.sourceforge.net

Reply via email to