Пример #1
0
void
ElemForEach::transformSelectedChildren(
			StylesheetExecutionContext&		executionContext,
			const ElemTemplateElement*		theTemplate,
			const NodeRefListBase&			sourceNodes,
			NodeRefListBase::size_type		sourceNodesCount) const
{
	if(executionContext.getTraceSelects() == true)
	{
		executionContext.traceSelect(
			*this,
			sourceNodes,
			m_selectPattern);
	}

	// Create an object to set and restore the context node list...
	const StylesheetExecutionContext::ContextNodeListPushAndPop		theContextNodeLisPushAndPop(
				executionContext,
				sourceNodes);

	for(NodeRefListBase::size_type i = 0; i < sourceNodesCount; i++) 
	{
		XalanNode* const		childNode = sourceNodes.item(i);
		assert(childNode != 0);

		transformChild(
				executionContext,
				*this,
				theTemplate,
				childNode);
	}
}
Пример #2
0
void
ElemMessage::execute(StylesheetExecutionContext&	executionContext) const
{
	ElemTemplateElement::execute(executionContext);

	StylesheetExecutionContext::GetAndReleaseCachedString	theResult(executionContext);

	const XalanDOMString&	theString =
		childrenToString(
			executionContext,
			theResult.get());

	const LocatorType* const	theLocator = getLocator();

	executionContext.message(
			theString,
			executionContext.getCurrentNode(),
			theLocator);

	if (m_terminate == true)
	{
		if (theLocator != 0)
		{
			throw ElemMessageTerminateException(*theLocator, theString);
		}
		else
		{
			throw ElemMessageTerminateException(theString);
		}
	}
}
Пример #3
0
void
ElemAttributeSet::endElement(StylesheetExecutionContext& executionContext) const
{
    executionContext.popElementRecursionStack();
    executionContext.popCurrentStackFrameIndex();

    ElemUse::endElement(executionContext);
}
Пример #4
0
void
ElemUse::endElement(StylesheetExecutionContext&	executionContext) const
{
	if (m_attributeSetsNamesCount > 0)
	{
		executionContext.popInvoker();

		executionContext.popUseAttributeSetIndexesFromStack();
	}
}
Пример #5
0
void
ElemPI::endElement(StylesheetExecutionContext&  executionContext) const
{
    endChildrenToString(executionContext);

    XalanDOMString&     piData =
        executionContext.getAndPopCachedString();

    const XalanDOMString&   piName =
        executionContext.getAndPopCachedString();

    XalanDOMString::iterator    theEnd =
        piData.end();

    XalanDOMString::iterator    theCurrent =
        piData.begin();

    // We need to fix up any occurrences of the sequence '?>' in
    // the PI's data by inserting a space between them.
    while (theCurrent != theEnd)
    {
        const XalanDOMChar  theChar = *theCurrent;

        if (theChar == XalanUnicode::charQuestionMark)
        {
            XalanDOMString::iterator    theNext =
                theCurrent + 1;

            if (theNext != theEnd &&
                *theNext == XalanUnicode::charGreaterThanSign)
            {
                theCurrent =
                    piData.insert(
                        theNext,
                        XalanUnicode::charSpace);

                theEnd = piData.end();

                // Move forward, since we're not interested in
                // the '>' character.
                ++theCurrent;
            }
        }

        ++theCurrent;
    }

    executionContext.processingInstruction(
                piName.c_str(),
                piData.c_str());

    executionContext.popCopyTextNodesOnly();
}
Пример #6
0
void
ElemTextLiteral::execute(StylesheetExecutionContext&    executionContext) const
{
    ElemTemplateElement::execute(executionContext);

    if (disableOutputEscaping() == false)
    {
        executionContext.characters(m_ch, 0, m_length);
    }
    else
    {
        executionContext.charactersRaw(m_ch, 0, m_length);
    }
}
Пример #7
0
const XObjectPtr
ElemVariable::getValue(
			StylesheetExecutionContext&		executionContext,
			XalanNode*						sourceNode) const
{
	if(m_selectPattern == 0)
	{
		if (getFirstChildElem() == 0)
		{
			return executionContext.getXObjectFactory().createStringReference(s_emptyString);
		}
		else
		{
			return executionContext.createXResultTreeFrag(*this, sourceNode);
		}
	}
	else
	{
		XObjectPtr	theValue;

		XalanNode* const	theCurrentNode = executionContext.getCurrentNode();
		
		if (theCurrentNode == sourceNode)
		{
			theValue = m_selectPattern->execute(*this, executionContext);
		}
		else
		{
			const XPathExecutionContext::CurrentNodePushAndPop	theCurrentNodePushAndPop(executionContext, sourceNode);

			theValue = m_selectPattern->execute(*this, executionContext);
		}

		if(0 != executionContext.getTraceListeners())
		{
			executionContext.fireSelectEvent(
				SelectionEvent(
					executionContext,
					sourceNode,
					*this,
					StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("select")),
					*m_selectPattern,
					theValue));
		}

		return theValue;
	}
}
Пример #8
0
void
ElemAttributeSet::execute(StylesheetExecutionContext&   executionContext) const
{
    typedef StylesheetExecutionContext::SetAndRestoreCurrentStackFrameIndex     SetAndRestoreCurrentStackFrameIndex;
    typedef StylesheetExecutionContext::ElementRecursionStackPusher             ElementRecursionStackPusher;

    // This will push and pop the stack automatically...
    ElementRecursionStackPusher     thePusher(executionContext, this);

    // Make sure only global variables are visible during execution...
    SetAndRestoreCurrentStackFrameIndex     theSetAndRestore(
                    executionContext, 
                    executionContext.getGlobalStackFrameIndex());

    ElemUse::execute(executionContext);

    const ElemTemplateElement*  attr = getFirstChildElem();

    while(0 != attr)
    {
        attr->execute(executionContext);

        attr = attr->getNextSiblingElem();
    }
}
void
ElemTemplate::endElement(StylesheetExecutionContext& executionContext) const
{
    executionContext.popCurrentTemplate();
    
    endExecuteChildren(executionContext);
}
void
NamespacesHandler::outputResultNamespaces(
            StylesheetExecutionContext&     theExecutionContext,
            bool                            supressDefault) const
{
    // Write out the namespace declarations...
    if (m_namespaceDeclarations.empty() == false)
    {
        const NamespaceExtendedVectorType::const_iterator   theEnd =
                m_namespaceDeclarations.end();

        NamespaceExtendedVectorType::const_iterator i =
                m_namespaceDeclarations.begin();

        for(; i != theEnd; ++i)
        {
            const NamespaceExtended&    theNamespace = *i;

            const XalanDOMString&       thePrefix = theNamespace.getPrefix();

            // If we're not supposed to suppress the default namespace, or
            // there's a prefix (so it's not the default), we can continue
            // to see if we need to add the result namespace.
            if (supressDefault == false ||
                length(thePrefix) != 0)
            {
                const XalanDOMString&       theResultURI = theNamespace.getURI();
                assert(length(theNamespace.getResultAttributeName()) > 0);

                // Get the any namespace declaration currently active for the
                // prefix.
                const XalanDOMString* const     desturi =
                    theExecutionContext.getResultNamespaceForPrefix(thePrefix);

                // Is there already an active namespace declaration?
                if(desturi == 0 || !equals(theResultURI, *desturi))
                {
                    // No, so add one...
                    theExecutionContext.addResultAttribute(theNamespace.getResultAttributeName(), theResultURI);
                }
            }
        }
    }
}
Пример #11
0
void
ElemElement::fixupDefaultNamespace(StylesheetExecutionContext&	executionContext) const
{
	// OK, now let's check to make sure we don't have to change the default namespace...
	const XalanDOMString* const		theCurrentDefaultNamespace =
				executionContext.getResultNamespaceForPrefix(s_emptyString);

	const XalanDOMString* const		theElementDefaultNamespace =
				getNamespacesHandler().getNamespace(s_emptyString);

	if (theCurrentDefaultNamespace != 0)
	{
		if (theElementDefaultNamespace == 0)
		{
			// There was no default namespace, so we have to turn the
			// current one off.
			executionContext.addResultAttribute(DOMServices::s_XMLNamespace, s_emptyString);
		}
		else if (equals(*theCurrentDefaultNamespace, *theElementDefaultNamespace) == false)
		{
			// There is a default namespace, but it's different from the current one,
			// so we have to change it.
			executionContext.addResultAttribute(DOMServices::s_XMLNamespace, *theElementDefaultNamespace);
		}
	}
	else
	{
		// There's no current default namespace in the result tree, but there may be
		// on for this xsl:element instance, so we have to add it, if so.
		const XalanDOMString&	theParentDefaultNamespace =
					getParentDefaultNamespace();

		if (theElementDefaultNamespace != 0)
		{
			if (length(theParentDefaultNamespace) == 0 || theParentDefaultNamespace != *theElementDefaultNamespace)
			{
				executionContext.addResultAttribute(DOMServices::s_XMLNamespace, *theElementDefaultNamespace);
			}
		}
	}
}
Пример #12
0
void
ElemForEach::execute(StylesheetExecutionContext&	executionContext) const
{
	assert(m_selectPattern != 0);
	assert(executionContext.getCurrentNode() != 0);

	StylesheetExecutionContext::PushAndPopCurrentTemplate	thePushAndPop(executionContext, 0);

	if (hasChildren() == true)
	{
		transformSelectedChildren(
			executionContext,
			this);
	}
}
Пример #13
0
void
ElemVariable::execute(StylesheetExecutionContext&	executionContext) const
{
	assert(m_qname != 0);

	ParentType::execute(executionContext);

	const XObjectPtr	theValue(getValue(executionContext, executionContext.getCurrentNode()));

	if (theValue.null() == false)
	{
		executionContext.pushVariable(
				*m_qname,
				theValue,
				getParentNodeElem());
	}
	else
	{
		executionContext.pushVariable(
				*m_qname,
				this,
				getParentNodeElem());
	}
}
Пример #14
0
void
ElemForEach::transformSelectedChildren(
			StylesheetExecutionContext&		executionContext,
			const ElemTemplateElement*		theTemplate) const
{
	assert(m_selectPattern != 0);
	assert(m_sortElemsCount == m_sortElems.size());

	if (m_sortElemsCount == 0)
	{
		selectAndSortChildren(
					executionContext,
					theTemplate,
					0,
					executionContext.getCurrentStackFrameIndex());
	}
	else
	{
		typedef NodeSorter::NodeSortKeyVectorType					NodeSortKeyVectorType;
		typedef StylesheetExecutionContext::BorrowReturnNodeSorter	BorrowReturnNodeSorter;

		BorrowReturnNodeSorter	sorter(executionContext);

		NodeSortKeyVectorType&	keys = sorter->getSortKeys();
		assert(keys.empty() == true);

		CollectionClearGuard<NodeSortKeyVectorType>		guard(keys);

		// Reserve the space now...
		keys.reserve(m_sortElemsCount);

		// Get some temporary strings to use for evaluting the AVTs...
		XPathExecutionContext::GetAndReleaseCachedString	theTemp1(executionContext);

		XalanDOMString&		langString = theTemp1.get();

		XPathExecutionContext::GetAndReleaseCachedString	theTemp2(executionContext);

		XalanDOMString&		scratchString = theTemp2.get();

		// March backwards, performing a sort on each xsl:sort child.
		// Probably not the most efficient method.
		for(SortElemsVectorType::size_type	i = 0; i < m_sortElemsCount; i++)
		{
			const ElemSort* const	sort = m_sortElems[i];
			assert(sort != 0);

			const AVT* avt = sort->getLangAVT();

			if(0 != avt)
			{
				avt->evaluate(langString, *this, executionContext);
			}

			avt = sort->getDataTypeAVT();

			if(0 != avt)
			{
				avt->evaluate(scratchString, *this, executionContext);
			}			

			bool	treatAsNumbers = false;

			if (isEmpty(scratchString) == false)
			{
				if (equals(scratchString, Constants::ATTRVAL_DATATYPE_NUMBER) == true)
				{
					treatAsNumbers = true;
				}
				else if (equals(scratchString, Constants::ATTRVAL_DATATYPE_TEXT) == false)
				{
					const XalanQNameByValue		theQName(scratchString, this);

					if (theQName.getNamespace().length() == 0)
					{
						executionContext.error(
							XalanMessageLoader::getMessage(XalanMessages::XslSortDataTypeMustBe),
							executionContext.getCurrentNode(),
							sort->getLocator());
					}
					else
					{
						executionContext.warn(
							XalanMessageLoader::getMessage(XalanMessages::XslSortHasUnlnownDataType),
							executionContext.getCurrentNode(),
							sort->getLocator());
					}
				}
			}

			clear(scratchString);

			avt = sort->getOrderAVT();

			if(0 != avt)
			{
				avt->evaluate(scratchString, *this, executionContext);
			}			

			bool	descending = false;
			
			if (isEmpty(scratchString) == false)
			{
				if (equals(scratchString, Constants::ATTRVAL_ORDER_DESCENDING) == true)
				{
					descending = true;
				}
				else if (equals(scratchString, Constants::ATTRVAL_ORDER_ASCENDING) == false)
				{
					executionContext.error(
						XalanMessageLoader::getMessage(XalanMessages::XslSortMustBeAscendOrDescend),
						executionContext.getCurrentNode(),
						sort->getLocator());
				}
			}

			clear(scratchString);

			avt = sort->getCaseOrderAVT();

			if(0 != avt)
			{
				avt->evaluate(scratchString, *this, executionContext);
			}			

			XalanCollationServices::eCaseOrder	caseOrder = XalanCollationServices::eDefault;

			if (isEmpty(scratchString) == false)
			{
				if (equals(scratchString, Constants::ATTRVAL_CASEORDER_UPPER) == true)
				{
					caseOrder = XalanCollationServices::eUpperFirst;
				}
				else if (equals(scratchString, Constants::ATTRVAL_CASEORDER_LOWER) == true)
				{
					caseOrder = XalanCollationServices::eLowerFirst;
				}
				else
				{
					executionContext.error(
						XalanMessageLoader::getMessage(XalanMessages::XslSortCaseOrderMustBe),
						executionContext.getCurrentNode(),
						sort->getLocator());
				}
			}

			clear(scratchString);

			keys.push_back(
					NodeSortKey(
						executionContext,
						sort->getSelectPattern(),
						treatAsNumbers,
						descending,
						caseOrder,
						langString,
						*this));
		}

		selectAndSortChildren(
					executionContext,
					theTemplate,
					sorter.get(),
					executionContext.getCurrentStackFrameIndex());
	}
}
Пример #15
0
void
ElemForEach::selectAndSortChildren(
			StylesheetExecutionContext&		executionContext,
			const ElemTemplateElement*		theTemplate,
			NodeSorter*						sorter,
			int								selectStackFrameIndex) const
{
	typedef StylesheetExecutionContext::SetAndRestoreCurrentStackFrameIndex		SetAndRestoreCurrentStackFrameIndex;

	assert(m_selectPattern != 0);

	typedef XPathExecutionContext::BorrowReturnMutableNodeRefList	BorrowReturnMutableNodeRefList;

	BorrowReturnMutableNodeRefList	theGuard(executionContext);

	const NodeRefListBase*	sourceNodes = 0;

	XObjectPtr				xobjectResult;

	{
		SetAndRestoreCurrentStackFrameIndex		theSetAndRestore(
					executionContext,
					selectStackFrameIndex);

		xobjectResult = m_selectPattern->execute(
						*this,
						executionContext,
						*theGuard);

		if (xobjectResult.null() == true)
		{
			sourceNodes = &*theGuard;
		}
		else
		{
			theGuard.release();

			sourceNodes = &xobjectResult->nodeset();
		}
	}

	if(0 != executionContext.getTraceListeners())
	{
		executionContext.fireSelectEvent(
				SelectionEvent(
					executionContext, 
					executionContext.getCurrentNode(),
					*this,
					StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("select")),
					*m_selectPattern,
					*sourceNodes));
	}

	const NodeRefListBase::size_type	nNodes = sourceNodes->getLength();

	if (nNodes > 0)
	{
		// If there's not NodeSorter, or we've only selected one node,
		// then just do the transform...
		if (sorter == 0 || nNodes == 1)
		{
			transformSelectedChildren(
				executionContext,
				theTemplate,
				*sourceNodes,
				nNodes);
		}
		else
		{
			typedef StylesheetExecutionContext::SetAndRestoreCurrentStackFrameIndex		SetAndRestoreCurrentStackFrameIndex;
			typedef StylesheetExecutionContext::ContextNodeListPushAndPop				ContextNodeListPushAndPop;
			typedef StylesheetExecutionContext::BorrowReturnMutableNodeRefList			BorrowReturnMutableNodeRefList;

			BorrowReturnMutableNodeRefList	sortedSourceNodes(executionContext);

			*sortedSourceNodes = *sourceNodes;

			{
				SetAndRestoreCurrentStackFrameIndex		theStackFrameSetAndRestore(
						executionContext,
						selectStackFrameIndex);

				ContextNodeListPushAndPop	theContextNodeListPushAndPop(
						executionContext,
						*sourceNodes);

				sorter->sort(executionContext, *sortedSourceNodes);
			}

			transformSelectedChildren(
				executionContext,
				theTemplate,
				*sortedSourceNodes,
				nNodes);
		}
	}
}
Пример #16
0
void
ElemLiteralResult::execute(StylesheetExecutionContext&	executionContext) const
{
	const XalanDOMString&	theElementName = getElementName();

	executionContext.startElement(c_wstr(theElementName));

	ElemUse::execute(executionContext);

	const NamespacesHandler&	theNamespacesHandler = getNamespacesHandler();

	theNamespacesHandler.outputResultNamespaces(executionContext);

	if (hasPrefix() == false)
	{
		// OK, let's check to make sure we don't have to change the default namespace...
		const XalanDOMString* const		theCurrentDefaultNamespace =
					executionContext.getResultNamespaceForPrefix(s_emptyString);

		if (theCurrentDefaultNamespace != 0)
		{
			const XalanDOMString* const		theElementDefaultNamespace =
							theNamespacesHandler.getNamespace(s_emptyString);

			if (theElementDefaultNamespace == 0)
			{
				// There was no default namespace, so we have to turn the
				// current one off.
				executionContext.addResultAttribute(DOMServices::s_XMLNamespace, s_emptyString);
			}
			else if (equals(*theCurrentDefaultNamespace, *theElementDefaultNamespace) == false)
			{
				executionContext.addResultAttribute(DOMServices::s_XMLNamespace, *theElementDefaultNamespace);
			}
		}
	}

	if(m_avtsCount > 0)
	{
		StylesheetExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

		XalanDOMString&		theStringedValue = theGuard.get();

		for(unsigned int i = 0; i < m_avtsCount; ++i)
		{
			const AVT* const	avt = m_avts[i];

			const XalanDOMString&	theName = avt->getName();

			avt->evaluate(theStringedValue, *this, executionContext);

			executionContext.addResultAttribute(theName, theStringedValue);

			theStringedValue.clear();
		}
	}

	executeChildren(executionContext);

	executionContext.endElement(c_wstr(theElementName));
}
Пример #17
0
void
ElemElement::execute(StylesheetExecutionContext&		executionContext) const
{
	StylesheetExecutionContext::GetAndReleaseCachedString	elemNameGuard(executionContext);

	XalanDOMString&		elemName = elemNameGuard.get();

	m_nameAVT->evaluate(elemName, *this, executionContext);

	bool	isIllegalElement = !XalanQName::isValidQName(elemName);

	if (isIllegalElement == true)
	{
		executionContext.warn(
			XalanMessageLoader::getMessage(XalanMessages::IllegalElementName_1Param, elemName),
			executionContext.getCurrentNode(),
			getLocator());

		ElemUse::doExecute(executionContext, false);

		doExecuteChildren(executionContext, true);
	}
	else
	{
		StylesheetExecutionContext::GetAndReleaseCachedString	elemNameSpaceGuard(executionContext);

		XalanDOMString&		elemNameSpace = elemNameSpaceGuard.get();

		if (m_namespaceAVT != 0)
		{
			m_namespaceAVT->evaluate(elemNameSpace, *this, executionContext);
		}

		XalanDOMString::size_type	namespaceLen = length(elemNameSpace);

		bool	foundResultNamespaceForPrefix = false;

		XalanDOMString::size_type			len = length(elemName);

		const XalanDOMString::size_type		indexOfNSSep = indexOf(elemName, XalanUnicode::charColon);

		const bool	havePrefix = indexOfNSSep == len ? false : true;

		StylesheetExecutionContext::GetAndReleaseCachedString	prefixGuard(executionContext);

		XalanDOMString&		prefix = prefixGuard.get();

		if (havePrefix == true)
		{
			substring(elemName, prefix, 0, indexOfNSSep);

			const XalanDOMString* const		theNamespace =
				executionContext.getResultNamespaceForPrefix(prefix);

			if (theNamespace != 0)
			{
				foundResultNamespaceForPrefix = true;
			}
			else
			{
				const XalanDOMString* const		theNamespace =
					getNamespacesHandler().getNamespace(prefix);

				if(theNamespace == 0 && namespaceLen == 0)
				{
					executionContext.warn(
						XalanMessageLoader::getMessage(
							XalanMessages::CannotResolvePrefix_1Param,
							prefix),
						executionContext.getCurrentNode(),
						getLocator());

					if (m_namespaceAVT != 0)
					{
						elemName.erase(0, indexOfNSSep + 1);
					}
					else
					{
						isIllegalElement = true;

						executionContext.warn(
							XalanMessageLoader::getMessage(
								XalanMessages::IllegalElementName_1Param,
								elemName),
							executionContext.getCurrentNode(),
							getLocator());
					}
				}
				else if (theNamespace != 0 &&
						 namespaceLen == 0 &&
						 equals(prefix, DOMServices::s_XMLNamespace) == false)
				{
					elemNameSpace = *theNamespace;
				}
			}
		}

		if (isIllegalElement == false)
		{
			executionContext.startElement(c_wstr(elemName));   

			if(0 == m_namespaceAVT &&
			   (havePrefix == false || foundResultNamespaceForPrefix == true))
			{
				if (havePrefix == false)
				{
					fixupDefaultNamespace(executionContext);
				}
			}
			else
			{
				if(havePrefix == false)
				{
					if (namespaceLen > 0)
					{
						const XalanDOMString* const		theDefaultNamespace =
								executionContext.getResultNamespaceForPrefix(s_emptyString);

						if (theDefaultNamespace == 0 ||
							equals(*theDefaultNamespace, elemNameSpace) == false)
						{
							executionContext.addResultAttribute(
									DOMServices::s_XMLNamespace,
									elemNameSpace);
						}
					}
					else
					{
						// OK, the namespace we're generating is the default namespace,
						// so let's make sure that we really need it.  If we don't,
						// we end up with another xmlns="" on the element we're
						// generating.  Although this isn't really an error, it's
						// a bit unsightly, so let's suppress it...
						const XalanDOMString&	theParentDefaultNamespace =
								getParentDefaultNamespace();

						if (length(theParentDefaultNamespace) == 0)
						{
							if (executionContext.getResultNamespaceForPrefix(s_emptyString) != 0)
							{
								executionContext.addResultAttribute(DOMServices::s_XMLNamespace, elemNameSpace);
							}
						}
						else
						{
							executionContext.addResultAttribute(DOMServices::s_XMLNamespace, elemNameSpace);
						}
					}
				}
				else
				{
					const XalanDOMString* const		theNamespace =
							executionContext.getResultNamespaceForPrefix(prefix);

					if (theNamespace == 0 ||
						equals(*theNamespace, elemNameSpace) == false)
					{
						insert(prefix, 0, DOMServices::s_XMLNamespaceWithSeparator);

						executionContext.addResultAttribute(prefix, elemNameSpace);
					}
				}
			}
		}

		if (isIllegalElement == true)
		{
			ElemUse::doExecute(executionContext, false);

			doExecuteChildren(executionContext, true);
		}
		else
		{
			ElemUse::doExecute(executionContext, true);

			doExecuteChildren(executionContext, false);

			executionContext.endElement(c_wstr(elemName));
		}
	}
}
const XObjectPtr
VariablesStack::findXObject(
            const XalanQName&               name,
            StylesheetExecutionContext&     executionContext,
            bool                            fIsParam,
            bool                            fSearchGlobalSpace,
            bool&                           fNameFound)
{
    typedef VariableStackStackType::size_type   size_type;

    // findEntry() returns an index into the stack.  We should
    // _never_ take the address of anything in the stack, since
    // the address could change at unexpected times.
    const size_type     theEntryIndex =
        findEntry(name, fIsParam, fSearchGlobalSpace);

    if (theEntryIndex == m_stack.size())
    {
        fNameFound = false;

        return XObjectPtr();
    }
    else
    {
        assert(theEntryIndex < m_stack.size());

        fNameFound = true;

        assert(m_stack[theEntryIndex].getType() == StackEntry::eVariable ||
               m_stack[theEntryIndex].getType() == StackEntry::eParam ||
               m_stack[theEntryIndex].getType() == StackEntry::eActiveParam);

        const XObjectPtr&   theValue = m_stack[theEntryIndex].getValue();

        if (theValue.null() == false)
        {
            return theValue;
        }
        else
        {
            const ElemVariable* const   var = m_stack[theEntryIndex].getVariable();

            XObjectPtr                  theNewValue;

            if (var != 0)
            {
                XalanNode* const    doc = executionContext.getRootDocument();
                assert(doc != 0);

                XALAN_USING_STD(find)

                // See if the ElemVariable instance is already being evaluated...
                if (find(m_guardStack.begin(), m_guardStack.end(), var) != m_guardStack.end())
                {
                    const StylesheetExecutionContext::GetCachedString   theGuard(executionContext);

                    executionContext.error(
                        XalanMessageLoader::getMessage(
                            theGuard.get(),
                            XalanMessages::CircularVariableDefWasDetected),
                        doc,
                        var->getLocator());
                }

                m_guardStack.push_back(var);

#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
                executionContext.pushContextMarker();
#else
                // We need to set up a stack frame for the variable's execution...
                typedef StylesheetExecutionContext::PushAndPopContextMarker PushAndPopContextMarker;

                const PushAndPopContextMarker   theContextMarkerPushPop(executionContext);
#endif

                theNewValue = var->getValue(executionContext, doc);
                assert(theNewValue.null() == false);

#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
                executionContext.popContextMarker();
#endif

                assert(m_guardStack.empty() == false);

                m_guardStack.pop_back();

                m_stack[theEntryIndex].setValue(theNewValue);
                m_stack[theEntryIndex].activate();
            }

            return theNewValue;
        }
    }
bool
ElemExtensionCall::elementAvailable(StylesheetExecutionContext&     executionContext) const
{
    return executionContext.elementAvailable(*m_qname);
}