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 ElemForEach::execute(StylesheetExecutionContext& executionContext) const { assert(m_selectPattern != 0); assert(executionContext.getCurrentNode() != 0); StylesheetExecutionContext::PushAndPopCurrentTemplate thePushAndPop(executionContext, 0); if (hasChildren() == true) { transformSelectedChildren( executionContext, this); } }
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 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 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)); } } }
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 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()); } }