![]() |
|
|
|
#1 |
|
Hello,
I want to load a grammar which doesnt not come with a DOCTYPE declaration, I tried with those lines, and it doesn't work parser->setFeature(XMLUni::fgSAX2CoreValidation, true); parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, false) // Load grammar and cache it parser->loadGrammar(/path/to/my/file.dtd", Grammar: true); // enable grammar reuse parser->setFeature(XMLUni::fgXercesUseCachedGrammarInPars e, true); Actually, If the <! DOCTYPE validation SYSTEM "file.dtd" > declaration is present, it does the validation with the file in the current path, not the one I loaded in cache. if the <! DOCTYPE ... > is not there, it does not validate. for example, it would be nice if it were possible to override a DOCTYPE declaration Thank You, Delphin delphin.lecucq@gmail.com |
|
|
|
|
#2 |
|
Posts: n/a
|
Hi Delphin,
writes: > Hello, > > I want to load a grammar which doesnt not come with a DOCTYPE > declaration, > > I tried with those lines, and it doesn't work > > parser->setFeature(XMLUni::fgSAX2CoreValidation, true); > parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, false) What happens if you also add these? parser->setFeature(XMLUni::fgXercesDynamic, false); parser->setFeature(XMLUni::fgXercesSchema, true); parser->setFeature(XMLUni::fgXercesSchemaFullChecking, true); > > // Load grammar and cache it > parser->loadGrammar(/path/to/my/file.dtd", Grammar: > // enable grammar reuse > parser->setFeature(XMLUni::fgXercesUseCachedGrammarInPars e, true); > > Actually, If the <! DOCTYPE validation SYSTEM "file.dtd" > declaration > is present, it does the validation with the file in the current path, > not the one I loaded in cache. > if the <! DOCTYPE ... > is not there, it does not validate. > > for example, it would be nice if it were possible to override a DOCTYPE > declaration 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 |
|
|
|
#3 |
|
Posts: n/a
|
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 |
|