Example #1
0
DOMDocument *
XIncludeUtils::doXIncludeXMLFileDOM(const XMLCh *href,
                                    const XMLCh *relativeHref,
                                    DOMNode *includeNode,
                                    DOMDocument *parsedDocument,
                                    XMLEntityHandler* entityResolver){
    if (XIncludeUtils::isInCurrentInclusionHistoryStack(href)){
         /* including something back up the current history */
         XIncludeUtils::reportError(parsedDocument, XMLErrs::XIncludeCircularInclusionLoop,
              href, href);
         return NULL;
    }

    if (XMLString::equals(href, parsedDocument->getBaseURI())){
        /* trying to include itself */
        XIncludeUtils::reportError(parsedDocument, XMLErrs::XIncludeCircularInclusionDocIncludesSelf,
              href, href);
        return NULL;
    }

    /* Instantiate the DOM parser. */
    XercesDOMParser parser;
    parser.setDoNamespaces(true);
    /* don't want to recurse the xi processing here */
    parser.setDoXInclude(false);
    /* create the schema info nodes, so that we can detect conflicting notations */
    parser.setCreateSchemaInfo(true);
    XMLInternalErrorHandler xierrhandler;
    parser.setErrorHandler(&xierrhandler);

    DOMDocument *includedNode = NULL;
    try {
        InputSource* is=NULL;
        Janitor<InputSource> janIS(is);
        if(entityResolver) {
            XMLResourceIdentifier resIdentifier(XMLResourceIdentifier::ExternalEntity,
                                                relativeHref,
                                                NULL,
                                                NULL,
                                                includeNode->getBaseURI());
            is=entityResolver->resolveEntity(&resIdentifier);
            janIS.reset(is);
        }
        if(janIS.get()!=NULL)
            parser.parse(*janIS.get());
        else
            parser.parse(href);
        /* need to be able to release the parser but keep the document */
        if (!xierrhandler.getSawError() && !xierrhandler.getSawFatal())
            includedNode = parser.adoptDocument();
    }
    catch (const XMLException& /*toCatch*/)
    {
        XIncludeUtils::reportError(parsedDocument, XMLErrs::XIncludeResourceErrorWarning,
              href, href);
    }
    catch (const DOMException& /*toCatch*/)
    {
        XIncludeUtils::reportError(parsedDocument, XMLErrs::XIncludeResourceErrorWarning,
              href, href);
    }
    catch (...)
    {
        XIncludeUtils::reportError(parsedDocument, XMLErrs::XIncludeResourceErrorWarning,
             href, href);
    }

    //addDocumentURIToCurrentInclusionHistoryStack(href);

    if(includedNode != NULL){
        /* baseURI fixups - see http://www.w3.org/TR/xinclude/#base for details. */
        DOMElement *topLevelElement = includedNode->getDocumentElement();
        if (topLevelElement && topLevelElement->getNodeType() == DOMNode::ELEMENT_NODE ){
            XMLUri parentURI(includeNode->getBaseURI());
            XMLUri includedURI(includedNode->getBaseURI());

            /* if the paths differ we need to add a base attribute */
            if (!XMLString::equals(parentURI.getPath(), includedURI.getPath())){
                if (getBaseAttrValue(topLevelElement) == NULL){
                    /* need to calculate the proper path difference to get the relativePath */
                    topLevelElement->setAttribute(fgXIBaseAttrName, relativeHref);
                } else {
                    /* the included node has base of its own which takes precedence */
                    XIncludeLocation xil(getBaseAttrValue(topLevelElement));
                    if (getBaseAttrValue(includeNode) != NULL){
                        /* prepend any specific base modification of the xinclude node */
                        xil.prependPath(getBaseAttrValue(includeNode));
                    }
                    topLevelElement->setAttribute(fgXIBaseAttrName, xil.getLocation());
                }
            }
        }
    }
    return includedNode;
}