Hi Boris!
My understanding is that the loadGrammar works as a proxy to entity
resolver. In other words, when the parser sees
<! DOCTYPE validation SYSTEM "file.dtd" >
it normally calls entity resolver to locate file.dtd but before that it
consults the grammar cache to see if this grammar was already loaded.
So I think the reason why if does not work is because without the
above DOCTYPE there is nothing in the document that specifies against
which schema we should validate (note that nothing prevents you from
caching several unrelated schemas). In case of XML Schema, there is
the fgXercesSchemaExternalSchemaLocation property that allows you
to specify schemas for namespaces and thus trigger validation if
a document refers to one of those namespaces. In case of DTD, I don't
see any similar mechanism. You may also find the following article
interesting:
http://www-128.ibm.com/developerwork...x-xsdxerc.html
hth,
-boris
--
Boris Kolpackov
Code Synthesis Tools CC
http://www.codesynthesis.com
Open-Source, Cross-Platform C++ XML Data Binding
Thank you for your help, the article was interesting, but I wanted to
use DTD rather XSD because it is more simple and it is sufficient for
my project.
I finaly choosed to pass the DTD file name in the XML file this way :
<! DOCTYPE rootElement SYSTEM "relativeFileName.dtd" >
I have overloaded MyHandler::resolveEntity to return a
LocalFileInputSource using the application specific basePath and the
relativeFileName given in the XML Document.
//dtdPath is a member of MySAX2Handler that I init before to parse
void MySAX2Handler::setDTDPath(const char* dtdPath_) { dtdPath =
dtdPath_;}
InputSource* MySAX2Handler::resolveEntity(
const XMLCh *const publicId, const XMLCh *const systemId) {
XMLCh* transcoded = XMLString::transcode(dtdPath);
InputSource* inSrc = new LocalFileInputSource(transcoded,
systemId,
XMLPlatformUtils::fgMemoryManager);
XMLString::release(&transcoded);
return inSrc;
}
This way it works, but it does not seem to be the perfect solution.
Delphin