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); } }
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); } } }
void ElemAttributeSet::endElement(StylesheetExecutionContext& executionContext) const { executionContext.popElementRecursionStack(); executionContext.popCurrentStackFrameIndex(); ElemUse::endElement(executionContext); }
void ElemUse::endElement(StylesheetExecutionContext& executionContext) const { if (m_attributeSetsNamesCount > 0) { executionContext.popInvoker(); executionContext.popUseAttributeSetIndexesFromStack(); } }
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(); }
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); } }
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; } }
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); } } } } }
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); } } } }
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); } }
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()); } }
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()); } }
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); } } }
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)); }
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); }