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