Here is the relevant code that uses Xerces to parse the DOM (minus all the error checking):

XERCES_CPP_NAMESPACE::MemBufInputSource* inputSource = new XERCES_CPP_NAMESPACE::MemBufInputSource( (const XMLByte*)data, dataLength, cDOMUtilities::convertString( systemID ), false );

XERCES_CPP_NAMESPACE::XercesDOMParser* parser = new XERCES_CPP_NAMESPACE::XercesDOMParser(); parser->setValidationScheme( XERCES_CPP_NAMESPACE::XercesDOMParser::Val_Auto );
parser->setDoNamespaces( false );
parser->setDoSchema( false );
parser->setCreateEntityReferenceNodes( false );
parser->setCreateCommentNodes( false );

parser->parse( *inputSource );

return new cDOMDocument( parser->adoptDocument() ); //This is our wrapper class.

And the transform code:

domDocument->normalize(); //This is the Xerces DOMDocument.

XALAN_CPP_NAMESPACE::XalanTransformer transformer;

transformer.setEntityResolver( entityResolver ); //Our custom entity resolver.

//Set any parameters.
if( mParameterMap != NULL )
{
for( tltCore::cIterator<const tltCore::cMap<tltCore::cString*, tltCore::cString*>::cEntry*>* iterator = mParameterMap->getEntries()->createIterator(); iterator->isCurrentElementValid(); iterator->increment() )
   {
transformer.setStylesheetParam( *iterator->getCurrentElement()->getKey(), *iterator->getCurrentElement()->getValue() );
    }
}

XALAN_CPP_NAMESPACE::XSLTInputSource* inputSource = new XALAN_CPP_NAMESPACE::XSLTInputSource( mStringStream );

//Compile the stylesheet for possible later use.
const XALAN_CPP_NAMESPACE::XalanCompiledStylesheet* compiledStylesheet;
transformer.compileStylesheet( *inputSource, compiledStylesheet );

//Try to get the DOCTYPE.
const XALAN_CPP_NAMESPACE::StylesheetRoot* stylesheetRoot = compiledStylesheet->getStylesheetRoot();
tltCore::cString doctypeFormat = getDoctypeFormat( stylesheetRoot );
tltCore::cString doctypePublic = getDoctypePublic( stylesheetRoot );
tltCore::cString doctypeSystem = getDoctypeSystem( stylesheetRoot );

//Create the input classes to use the Xerces DOM.
XALAN_CPP_NAMESPACE::XercesDOMSupport xercesDOMSupport;
XALAN_CPP_NAMESPACE::XercesParserLiaison xercesParserLiason;

//NOTE: Tried several different things here for the system id, including hardcoding the correct path to the XML file. const XALAN_CPP_NAMESPACE::XercesDOMWrapperParsedSource parsedSource( domDocument, xercesParserLiason, xercesDOMSupport, XALAN_CPP_NAMESPACE::XalanDOMString( domDocument->getDocumentURI() ) );

//Create the Xerces DOM output.
XERCES_CPP_NAMESPACE::DOMImplementation* domImplementation =
     XERCES_CPP_NAMESPACE::DOMImplementation::getImplementation();
XERCES_CPP_NAMESPACE::DOMDocument* outputDOMDocument;

if( !doctypeFormat.equals( "" ) && ( !doctypePublic.equals( "" ) || !doctypeSystem.equals( "" ) ) )
{
XERCES_CPP_NAMESPACE::DOMDocumentType* documentType = domImplementation->createDocumentType(
                      cDOMUtilities::convertString( doctypeFormat ),
                      cDOMUtilities::convertString( doctypePublic ),
                      cDOMUtilities::convertString( doctypeSystem ) );
outputDOMDocument = domImplementation->createDocument( NULL, NULL, documentType );
}
else
{
           outputDOMDocument = domImplementation->createDocument();
}

//Format the output from Xalan to Xerces.
XALAN_CPP_NAMESPACE::FormatterToXercesDOM xercesFormatter( outputDOMDocument, NULL );

transformer.transform( parsedSource, compiledStylesheet, xercesFormatter );

return new cDOMDocument( outputDOMDocument );

After that I use a Xerces DOMWriter to output the document to an HTML file. If I comment out the XercesDOMWrapperParsedSource stuff, and pass in the file name to the transformer, everything works as it should.

Thanks for taking a look!

Kelly

David Bertoni wrote:
Kelly Graus wrote:
Ok, that makes sense. And good news with the future inclusion of the XMLEntityResolver.

In the mean time, I got my custom entity resolver working when I use the path to the XML file in the transform call (before I wasn't setting the system IDs correctly in the InputSources, which was causing the working directory to be passed in to the entity resolver). However, when I try to use a Xerces DOM as the XML input, it doesn't seem to use the system id that the DOM has, or the system id that I set in the XercesDOMWrapperParsedSource, and ends up using the working directory. Is there another way to set the system id for the XML when using a Xerces DOM as the source?

It's hard to say without seeing some real source code. This could be a bug, or it could be a problem with your code.

Can you post a minimal amount of source code that reproduces the problem?

Dave

Reply via email to