Logo Search packages:      
Sourcecode: xalan version File versions  Download package

Stylesheet * XSLTEngineImpl::getStylesheetFromPIURL ( const XalanDOMString &  xslURLString,
XalanNode &  fragBase,
const XalanDOMString &  xmlBaseIdent,
bool  isRoot,
StylesheetConstructionContext &  constructionContext 
)

Reset the state of the XSL processor by reading in a new XSL stylesheet from a processing instruction.

Parameters:
xslURLString valid URI to an XSL stylesheet
fragBase base of tree if URI represents document fragment
xmlBaseIdent base identifier for stylesheet URI
isRoot true if stylesheet is root of tree
constructionContext context for construction of object
Returns:
pointer to stylesheet

Definition at line 632 of file XSLTEngineImpl.cpp.

References Stylesheet::create(), StylesheetHandler::endDocument(), error(), evalXPathStr(), Stylesheet::getMemoryManager(), m_stylesheetRoot, XObjectPtr::null(), Stylesheet::postConstruction(), and StylesheetHandler::startDocument().

Referenced by process().

{
    MemoryManager&          theMemoryManager =
        constructionContext.getMemoryManager();

    Stylesheet*             stylesheet = 0;

    const CCGetAndReleaseCachedString theGuard(constructionContext);
    XalanDOMString  &       stringHolder = theGuard.get();

    const CCGetAndReleaseCachedString theGuard1(constructionContext);
    XalanDOMString&     localXSLURLString = theGuard1.get();    
    
    trim(xslURLString, localXSLURLString);

    const XalanDOMString::size_type     fragIndex =
        indexOf(localXSLURLString, XalanUnicode::charNumberSign);

    if(fragIndex == 0)
    {
        const CCGetAndReleaseCachedString theGuard(constructionContext);

        XalanDOMString& fragID = theGuard.get();

        fragID.assign(localXSLURLString);

        const XalanElement*     nsNode = 0;

        const XalanNode::NodeType   theType = fragBase.getNodeType();

        if (theType == XalanNode::DOCUMENT_NODE)
        {
            const XalanDocument&    doc =
#if defined(XALAN_OLD_STYLE_CASTS)
                (const XalanDocument&)fragBase;
#else
                static_cast<const XalanDocument&>(fragBase);
#endif

            nsNode = doc.getDocumentElement(); 
        }
        else if (theType == XalanNode::ELEMENT_NODE)
        {
#if defined(XALAN_OLD_STYLE_CASTS)
            nsNode = (const XalanElement*)&fragBase;
#else
            nsNode = static_cast<const XalanElement*>(&fragBase);
#endif
        }
        else
        {
            XalanNode* const    node = fragBase.getParentNode();

            if  (node->getNodeType() == XalanNode::ELEMENT_NODE) 
            {
#if defined(XALAN_OLD_STYLE_CASTS)
                nsNode = (const XalanElement*)&fragBase;
#else
                nsNode = static_cast<XalanElement*>(node);
#endif
            }
            else
            {
                const CCGetAndReleaseCachedString theGuard(constructionContext);

                error(
                    XalanMessageLoader::getMessage(
                        theGuard.get(),
                        XalanMessages::CantFindFragment_1Param,
                        fragID));
            }
        }

        // Try a bunch of really ugly stuff to find the fragment.
        // What's the right way to do this?
        const CCGetAndReleaseCachedString theGuard3(constructionContext);

        XalanDOMString& ds = theGuard3.get();

        ds.append("id(");

        ds += fragID;
        ds.append(")");

        ElementPrefixResolverProxy      theProxy(nsNode, m_xpathEnvSupport, m_domSupport, theMemoryManager);

        XPathExecutionContextDefault    theExecutionContext(m_xpathEnvSupport,
                                                            m_domSupport,
                                                            m_xobjectFactory,
                                                            &fragBase,
                                                            0,
                                                            &theProxy);

        const XObjectPtr    xobj(evalXPathStr(ds, theExecutionContext));
        assert(xobj.null() == false);

        NodeRefList     nl( xobj->nodeset(), theMemoryManager);

        if(nl.getLength() == 0)
        {
            ds.assign("//*[@id='");
            ds += fragID;
            ds.append("']");

            const XObjectPtr    xobj(evalXPathStr(ds, theExecutionContext));
            assert(xobj.null() == false);

            nl = xobj->nodeset();

            if(nl.getLength() == 0)
            {
                ds.assign("//*[@name='");
                ds += fragID;
                ds.append("']");

                const XObjectPtr    xobj(evalXPathStr(ds, theExecutionContext));
                assert(xobj.null() == false);

                nl = xobj->nodeset();

                if(nl.getLength() == 0)
                {
                    // Well, hell, maybe it's an XPath...
                    const XObjectPtr    xobj(evalXPathStr(fragID, theExecutionContext));
                    assert(xobj.null() == false);

                    nl = xobj->nodeset();
                }
            }
        }

        if(nl.getLength() == 0)
        {
            const CCGetAndReleaseCachedString   theGuard(constructionContext);

            error(
                XalanMessageLoader::getMessage(
                    theGuard.get(),
                    XalanMessages::CantFindFragment_1Param,
                    fragID));
        }

        XalanNode* const    frag = nl.item(0);

        if(XalanNode::ELEMENT_NODE == frag->getNodeType())
        {
            XalanMemMgrAutoPtr<Stylesheet, true>    theGuard;

            if(isRoot)
            {
                StylesheetRoot* const   theLocalRoot =
                    constructionContext.create(stringHolder);

                stylesheet = theLocalRoot;

                m_stylesheetRoot = theLocalRoot;
            }
            else
            {
#if defined(XALAN_OLD_STYLE_CASTS)
                stylesheet = constructionContext.create( *((StylesheetRoot*)m_stylesheetRoot), stringHolder);
#else
                stylesheet = constructionContext.create( *const_cast<StylesheetRoot*>(m_stylesheetRoot), stringHolder);
#endif

                theGuard.reset(&theMemoryManager, stylesheet);
            }

            StylesheetHandler stylesheetProcessor(*stylesheet, constructionContext);

            FormatterTreeWalker tw(stylesheetProcessor,  theMemoryManager);

            stylesheetProcessor.startDocument();

            tw.traverseSubtree(frag);

            stylesheetProcessor.endDocument();

            stylesheet->postConstruction(constructionContext);

            theGuard.release();
        }
        else
        {
            const CCGetAndReleaseCachedString theGuard(constructionContext);

            error(
                XalanMessageLoader::getMessage(
                    theGuard.get(),
                    XalanMessages::NodePointedByFragment_1Param,
                    fragID));
        }
    }
    else
    {
        XalanMemMgrAutoPtr<Stylesheet, true>    theGuard;

        const XalanDocument* const  theOwnerDocument =
                fragBase.getNodeType() == XalanNode::DOCUMENT_NODE ?
#if defined(XALAN_OLD_STYLE_CASTS)
                (const XalanDocument*)&fragBase :
#else
                static_cast<const XalanDocument*>(&fragBase) :
#endif
                fragBase.getOwnerDocument();
        assert(theOwnerDocument != 0);

        // Catch any XMLExceptions thrown, since we may not
        // be able to resolve the URL.  In that case, the
        // parser will throw an error.  We do this because
        // we don't know what sort of EntityResolvers might
        // be active, so we never want to error out here.
        try
        {
            if (length(xmlBaseIdent) == 0)
            {
                URISupport::getURLStringFromString(
                            localXSLURLString,
                            m_xpathEnvSupport.findURIFromDoc(theOwnerDocument),
                            localXSLURLString);
            }
            else
            {
                URISupport::getURLStringFromString(
                            localXSLURLString,
                            xmlBaseIdent,
                            localXSLURLString);
            }
        }
        catch(const XERCES_CPP_NAMESPACE_QUALIFIER XMLException&)
        {
        }

        if(isRoot)
        {
            StylesheetRoot* const   theLocalRoot =
                    constructionContext.create(localXSLURLString);

            stylesheet = theLocalRoot;

            m_stylesheetRoot = theLocalRoot;
        }
        else
        {
            stylesheet = Stylesheet::create(
                            theMemoryManager,
#if defined(XALAN_OLD_STYLE_CASTS)
                            *(StylesheetRoot*)m_stylesheetRoot,
#else
                            *const_cast<StylesheetRoot*>(m_stylesheetRoot),
#endif
                            localXSLURLString,
                            constructionContext);

            theGuard.reset(&theMemoryManager, stylesheet);
        }

        StylesheetHandler stylesheetProcessor(*stylesheet, constructionContext);

        typedef StylesheetConstructionContext::URLAutoPtrType   URLAutoPtrType;

        URLAutoPtrType  xslURL(constructionContext.getURLFromString(localXSLURLString));

        XSLTInputSource     inputSource(xslURL->getURLText(), theMemoryManager);

        m_parserLiaison.parseXMLStream(inputSource, stylesheetProcessor, s_emptyString);

        stylesheet->postConstruction(constructionContext);

        theGuard.release();
    }

    return stylesheet;
}


Generated by  Doxygen 1.6.0   Back to index