I've really tried to find out what I am doing wrong here.
Basically, I am using my own DOMLSResourceResolver to use a local copy of XHTML 1.1 Strict DTD for many hundreds of XHTML documents. But the parser seems to be refusing to cache it, or find it - so it is asking for a new copy for each document.

I am sure I am doing something wrong - but what I noticed was that srcToFill->getSystemId() is not returning the SystemID that I set.

Here are the parser settings I am using.
dc->setParameter(XMLUni::fgDOMResourceResolver,myResourceHandler);
        
dc->setParameter(XMLUni::fgXercesValidationErrorAsFatal, false);             
dc->setParameter(XMLUni::fgXercesUserAdoptsDOMDocument, true);               
dc->setParameter(XMLUni::fgXercesUseCachedGrammarInParse, true);             
dc->setParameter(XMLUni::fgXercesSchema, true);      
dc->setParameter(XMLUni::fgXercesSchemaFullChecking, true);  
dc->setParameter(XMLUni::fgXercesContinueAfterFatalError, true);             
dc->setParameter(XMLUni::fgXercesCacheGrammarFromParse, true);               
dc->setParameter(XMLUni::fgDOMElementContentWhitespace, false);      
dc->setParameter(XMLUni::fgDOMNamespaces, true);
dc->setParameter(XMLUni::fgDOMDatatypeNormalization, true);
dc->setParameter(XMLUni::fgXercesLoadExternalDTD, false);
dc->setParameter(XMLUni::fgXercesIgnoreCachedDTD, false);
dc->setParameter(XMLUni::fgDOMValidateIfSchema, true);

My call traces were as follows:

void TraverseSchema::preprocessImport(const DOMElement* const elem)

InputSource* srcToFill = resolveSchemaLocation (schemaLocation,XMLResourceIdentifier::SchemaImport, nameSpace);

(which goes to)

InputSource* TraverseSchema::resolveSchemaLocation(const XMLCh* const loc, const XMLResourceIdentifier::ResourceIdentifierType resourceIdentitiferType,
                                const XMLCh* const nameSpace)


(which goes to)

InputSource* DOMLSParserImpl::resolveEntity( XMLResourceIdentifier* resourceIdentifier ) {
     if (fEntityResolver) {
DOMLSInput* is = fEntityResolver- > resolveResource (resourceIdentifier >getResourceIdentifierType()==XMLResourceIdentifier::ExternalEntity? XMLUni::fgDOMDTDType:XMLUni::fgDOMXMLSchemaType,
                 resourceIdentifier->getNameSpace(),
                 resourceIdentifier->getPublicId(),
                 resourceIdentifier->getSystemId(),
                resourceIdentifier->getBaseURI());
        if (is)
return new (getMemoryManager()) Wrapper4DOMLSInput(is, fEntityResolver, true, getMemoryManager());
    }
    if (fXMLEntityResolver) {
        return(fXMLEntityResolver->resolveEntity(resourceIdentifier));
    }
    return 0;
}

//DOMLSParserImpl::resolveEntity calls my resolveResource which I have added using XMLUni::fgDOMResourceResolver //where I construct a new DOMLSInput with createLSInput //which contains, in this case, a local copy of XHTML 1.1 Strict DTD.
[...]
DOMLSInput* srcToFill = ((DOMImplementationLS*)Manager::parser()- >impl)->createLSInput(); srcToFill->setStringData(my_dtd_xhtml1_grammar); //This DTD is already XMLCh encoded, and is definitely correct.
        srcToFill->setEncoding(XMLUni::fgXMLChEncodingString);
        srcToFill->setPublicId(publicId);
        srcToFill->setSystemId(systemId);
        return srcToFill;
[...]

The returned LSInput bubbles back upt to preprocessImport,

TraverseSchema, Line 830:
const XMLCh* importURL = srcToFill->getSystemId(); <<-- returns NULL even though I set it in the DOMLSInput.


Reply via email to