XObjectPtr FunctionGenerateID::execute( XPathExecutionContext& executionContext, XalanNode* /* context */, const XObjectPtr arg1, const LocatorType* locator) const { assert(arg1.null() == false); const NodeRefListBase& theNodeList = arg1->nodeset(); if (theNodeList.getLength() == 0) { return executionContext.getXObjectFactory().createStringReference(s_emptyString); } else { return execute(executionContext, theNodeList.item(0), locator); } }
void TXFMXPath::evaluateExpr(DOMNode *h, safeBuffer inexpr) { // Temporarily add any necessary name spaces into the document XSECXPathNodeList addedNodes; setXPathNS(document, XPathAtts, addedNodes, formatter, mp_nse); XPathProcessorImpl xppi; // The processor XercesParserLiaison xpl; #if XALAN_VERSION_MAJOR == 1 && XALAN_VERSION_MINOR > 10 XercesDOMSupport xds(xpl); #else XercesDOMSupport xds; #endif XPathEvaluator xpe; XPathFactoryDefault xpf; XPathConstructionContextDefault xpcc; XalanDocument * xd; XalanNode * contextNode; // Xalan can throw exceptions in all functions, so do one broad catch point. try { // Map to Xalan xd = xpl.createDocument(document); // For performing mapping XercesDocumentWrapper *xdw = xpl.mapDocumentToWrapper(xd); XercesWrapperNavigator xwn(xdw); // Map the "here" node - but only if part of current document XalanNode * hereNode = NULL; if (h->getOwnerDocument() == document) { hereNode = xwn.mapNode(h); if (hereNode == NULL) { hereNode = findHereNodeFromXalan(&xwn, xd, h); if (hereNode == NULL) { throw XSECException(XSECException::XPathError, "Unable to find here node in Xalan Wrapper map"); } } } // Now work out what we have to set up in the new processing TXFMBase::nodeType inputType = input->getNodeType(); XalanDOMString cd; // For the moment assume the root is the context const XalanDOMChar * cexpr; safeBuffer contextExpr; switch (inputType) { case DOM_NODE_DOCUMENT : case DOM_NODE_XPATH_NODESET : // do XPath over the whole document and, if the input was an // XPath Nodeset, then later intersect the result with the input nodelist cd = XalanDOMString("/"); // Root node cexpr = cd.c_str(); // The context node is the "root" node contextNode = xpe.selectSingleNode( xds, xd, cexpr, xd->getDocumentElement()); break; case DOM_NODE_DOCUMENT_FRAGMENT : { // Need to map the DOM_Node that we are given from the input to the appropriate XalanNode // Create the XPath expression to find the node if (input->getFragmentId() != NULL) { contextExpr.sbTranscodeIn("//descendant-or-self::node()[attribute::Id='"); contextExpr.sbXMLChCat(input->getFragmentId()); contextExpr.sbXMLChCat("']"); // Map the node contextNode = xpe.selectSingleNode( xds, xd, contextExpr.rawXMLChBuffer(), //XalanDOMString((char *) contextExpr.rawBuffer()).c_str(), xd->getDocumentElement()); if (contextNode == NULL) { // Last Ditch contextNode = xwn.mapNode(input->getFragmentNode()); } } else contextNode = xwn.mapNode(input->getFragmentNode()); if (contextNode == NULL) { // Something wrong throw XSECException(XSECException::XPathError, "Error mapping context node"); } break; } default : throw XSECException(XSECException::XPathError); // Should never get here } safeBuffer str; XPathEnvSupportDefault xpesd; XObjectFactoryDefault xof; XPathExecutionContextDefault xpec(xpesd, xds, xof); ElementPrefixResolverProxy pr(xd->getDocumentElement(), xpesd, xds); // Work around the fact that the XPath implementation is designed for XSLT, so does // not allow here() as a NCName. // THIS IS A KLUDGE AND SHOULD BE DONE BETTER int offset = 0; safeBuffer k(KLUDGE_PREFIX); k.sbStrcatIn(":"); offset = inexpr.sbStrstr("here()"); while (offset >= 0) { if (offset == 0 || offset == 1 || (!(inexpr[offset - 1] == ':' && inexpr[offset - 2] != ':') && separator(inexpr[offset - 1]))) { inexpr.sbStrinsIn(k.rawCharBuffer(), offset); } offset = inexpr.sbOffsetStrstr("here()", offset + 11); } // Install the External function in the Environment handler if (hereNode != NULL) { xpesd.installExternalFunctionLocal(XalanDOMString(URI_ID_DSIG), XalanDOMString("here"), DSIGXPathHere(hereNode)); } str.sbStrcpyIn("(descendant-or-self::node() | descendant-or-self::node()/attribute::* | descendant-or-self::node()/namespace::*)["); str.sbStrcatIn(inexpr); str.sbStrcatIn("]"); XPath * xp = xpf.create(); XalanDOMString Xexpr((char *) str.rawBuffer()); xppi.initXPath(*xp, xpcc, Xexpr, pr); // Now resolve XObjectPtr xObj = xp->execute(contextNode, pr, xpec); // Now map to a list that others can use (naieve list at this time) const NodeRefListBase& lst = xObj->nodeset(); int size = (int) lst.getLength(); const DOMNode *item; for (int i = 0; i < size; ++ i) { if (lst.item(i) == xd) m_XPathMap.addNode(document); else { item = xwn.mapNode(lst.item(i)); m_XPathMap.addNode(item); } } if (inputType == DOM_NODE_XPATH_NODESET) { //the input list was a XPATH nodeset, so we must intersect the // results of the XPath processing done above with the input nodeset m_XPathMap.intersect(input->getXPathNodeList()); } } catch (XSLException &e) { safeBuffer msg; // Whatever happens - fix any changes to the original document clearXPathNS(document, addedNodes, formatter, mp_nse); // Collate the exception message into an XSEC message. msg.sbTranscodeIn("Xalan Exception : "); #if defined (XSEC_XSLEXCEPTION_RETURNS_DOMSTRING) msg.sbXMLChCat(e.getType().c_str()); #else msg.sbXMLChCat(e.getType()); #endif msg.sbXMLChCat(" caught. Message : "); msg.sbXMLChCat(e.getMessage().c_str()); throw XSECException(XSECException::XPathError, msg.rawXMLChBuffer()); } clearXPathNS(document, addedNodes, formatter, mp_nse); }
XSECXPathNodeList * TXFMXPathFilter::evaluateSingleExpr(DSIGXPathFilterExpr *expr) { // Have a single expression that we wish to find the resultant nodeset // for XSECXPathNodeList addedNodes; setXPathNS(document, expr->mp_NSMap, addedNodes, mp_formatter, mp_nse); XPathProcessorImpl xppi; // The processor XercesParserLiaison xpl; #if XALAN_VERSION_MAJOR == 1 && XALAN_VERSION_MINOR > 10 XercesDOMSupport xds(xpl); #else XercesDOMSupport xds; #endif XPathEvaluator xpe; XPathFactoryDefault xpf; XPathConstructionContextDefault xpcc; XalanDocument * xd; XalanNode * contextNode; // Xalan can throw exceptions in all functions, so do one broad catch point. try { // Map to Xalan xd = xpl.createDocument(document); // For performing mapping XercesDocumentWrapper *xdw = xpl.mapDocumentToWrapper(xd); XercesWrapperNavigator xwn(xdw); // Map the "here" node XalanNode * hereNode = NULL; hereNode = xwn.mapNode(expr->mp_xpathFilterNode); if (hereNode == NULL) { hereNode = findHereNodeFromXalan(&xwn, xd, expr->mp_exprTextNode); if (hereNode == NULL) { throw XSECException(XSECException::XPathFilterError, "Unable to find here node in Xalan Wrapper map"); } } // Now work out what we have to set up in the new processing XalanDOMString cd; // For XPath Filter, the root is always the context node cd = XalanDOMString("/"); // Root node // The context node is the "root" node contextNode = xpe.selectSingleNode( xds, xd, cd.c_str(), xd->getDocumentElement()); XPathEnvSupportDefault xpesd; XObjectFactoryDefault xof; XPathExecutionContextDefault xpec(xpesd, xds, xof); ElementPrefixResolverProxy pr(xd->getDocumentElement(), xpesd, xds); // Work around the fact that the XPath implementation is designed for XSLT, so does // not allow here() as a NCName. // THIS IS A KLUDGE AND SHOULD BE DONE BETTER int offset = 0; safeBuffer k(KLUDGE_PREFIX); k.sbStrcatIn(":"); // Map the expression into a local code page string (silly - should be XMLCh) safeBuffer exprSB; exprSB << (*mp_formatter << expr->m_expr.rawXMLChBuffer()); offset = exprSB.sbStrstr("here()"); while (offset >= 0) { if (offset == 0 || offset == 1 || (!(exprSB[offset - 1] == ':' && exprSB[offset - 2] != ':') && separator(exprSB[offset - 1]))) { exprSB.sbStrinsIn(k.rawCharBuffer(), offset); } offset = exprSB.sbOffsetStrstr("here()", offset + 11); } // Install the External function in the Environment handler if (hereNode != NULL) { xpesd.installExternalFunctionLocal(XalanDOMString(URI_ID_DSIG), XalanDOMString("here"), DSIGXPathHere(hereNode)); } XPath * xp = xpf.create(); XalanDOMString Xexpr((char *) exprSB.rawBuffer()); xppi.initXPath(*xp, xpcc, Xexpr, pr); // Now resolve XObjectPtr xObj = xp->execute(contextNode, pr, xpec); // Now map to a list that others can use (naieve list at this time) const NodeRefListBase& lst = xObj->nodeset(); int size = (int) lst.getLength(); const DOMNode *item; XSECXPathNodeList * ret; XSECnew(ret, XSECXPathNodeList); Janitor<XSECXPathNodeList> j_ret(ret); for (int i = 0; i < size; ++ i) { if (lst.item(i) == xd) ret->addNode(document); else { item = xwn.mapNode(lst.item(i)); ret->addNode(item); } } xpesd.uninstallExternalFunctionGlobal(XalanDOMString(URI_ID_DSIG), XalanDOMString("here")); clearXPathNS(document, addedNodes, mp_formatter, mp_nse); j_ret.release(); return ret; } catch (XSLException &e) { safeBuffer msg; // Whatever happens - fix any changes to the original document clearXPathNS(document, addedNodes, mp_formatter, mp_nse); // Collate the exception message into an XSEC message. msg.sbTranscodeIn("Xalan Exception : "); #if defined (XSEC_XSLEXCEPTION_RETURNS_DOMSTRING) msg.sbXMLChCat(e.getType().c_str()); #else msg.sbXMLChCat(e.getType()); #endif msg.sbXMLChCat(" caught. Message : "); msg.sbXMLChCat(e.getMessage().c_str()); throw XSECException(XSECException::XPathFilterError, msg.rawXMLChBuffer()); } catch (...) { clearXPathNS(document, addedNodes, mp_formatter, mp_nse); throw; } return NULL; }
bool TestPredicateResult( XPathProcessor& theXPathProcessor, XPathEnvSupport& theXPathEnvSupport, DOMSupport& theDOMSupport, XMLParserLiaison& theLiaison, XPathFactory& theXPathFactory, const XalanDOMString& theXMLFileURL, const XalanDOMString& theXSLFileURL, PrintWriter& thePrintWriter, XPathExecutionContext& theExecutionContext) { bool fError = false; XalanDocument* const theXMLDocument = ParseXML(theLiaison, theXMLFileURL); MemoryManagerType& theMemoryManager = theExecutionContext.getMemoryManager(); if (theXMLDocument != 0) { XalanDOMString theContextNodeMatchPattern(theMemoryManager); XalanDOMString theXPathString(theMemoryManager); if (GetXSLInput(theLiaison, theXSLFileURL, theContextNodeMatchPattern, theXPathString, theMemoryManager) == true) { XalanNode* const theContextNode = FindContextNode(theXPathProcessor, theXPathEnvSupport, theDOMSupport, theXPathFactory, theXMLDocument, theContextNodeMatchPattern, thePrintWriter, theExecutionContext); if (theContextNode != 0) { XalanElement* const theNamespaceContext = 0; ElementPrefixResolverProxy thePrefixResolver(theNamespaceContext, theXPathEnvSupport, theDOMSupport); NodeRefList theContextNodeList(theMemoryManager); XPath* const theXPath1 = theXPathFactory.create(); XPathConstructionContextDefault theXPathConstructionContext(theMemoryManager); XPathGuard theGuard1(theXPathFactory, theXPath1); XalanDOMString theResult(theMemoryManager); theXPathProcessor.initXPath(*theXPath1, theXPathConstructionContext, TranscodeFromLocalCodePage("following-sibling::*", theResult), thePrefixResolver); XPath* const theXPath2 = theXPathFactory.create(); XPathGuard theGuard2(theXPathFactory, theXPath2); theXPathProcessor.initXPath(*theXPath2, theXPathConstructionContext, TranscodeFromLocalCodePage("descendant::*", theResult), thePrefixResolver); bool fDump = false; if (fDump == true) { thePrintWriter.println(); thePrintWriter.println(); theXPath1->getExpression().dumpOpCodeMap(thePrintWriter); thePrintWriter.println(); theXPath1->getExpression().dumpTokenQueue(thePrintWriter); thePrintWriter.println(); thePrintWriter.println(); theXPath2->getExpression().dumpOpCodeMap(thePrintWriter); thePrintWriter.println(); theXPath2->getExpression().dumpTokenQueue(thePrintWriter); thePrintWriter.println(); thePrintWriter.println(); } XalanNode* theContextNode = theXMLDocument->getFirstChild()->getFirstChild(); for( ; theContextNode != 0; theContextNode = theContextNode->getNextSibling()) { if (theContextNode->getNodeType() != XalanNode::ELEMENT_NODE) { continue; } const XObjectPtr theResult1 = theXPath1->execute(theExecutionContext); try { assert(theResult1.null() == false); const NodeRefListBase& theResultList = theResult1->nodeset(); const unsigned int theLength = theResultList.getLength(); thePrintWriter.print("theResult1->str() == \""); thePrintWriter.print(theResult1->str()); thePrintWriter.print("\""); thePrintWriter.println(); if (theLength > 0) { for (unsigned int i = 0; i < theLength; i++) { thePrintWriter.print(theResultList.item(i)->getNodeName()); thePrintWriter.println(); } } } catch(...) { thePrintWriter.print("Execution of XPath "); thePrintWriter.print(theXPathString); thePrintWriter.println(" failed!"); } const XObjectPtr theResult2 = theXPath2->execute(theExecutionContext); try { assert(theResult2.null() == false); const NodeRefListBase& theResultList = theResult2->nodeset(); const int theLength = theResultList.getLength(); thePrintWriter.print("theResult2->str() == \""); thePrintWriter.print(theResult2->str()); thePrintWriter.print("\""); thePrintWriter.println(); if (theLength > 0) { for (int i = 0; i < theLength; i++) { thePrintWriter.print(theResultList.item(i)->getNodeName()); thePrintWriter.println(); } } } catch(...) { thePrintWriter.print("Execution of XPath "); thePrintWriter.print(theXPathString); thePrintWriter.println(" failed!"); } if (theResult1->equals(*theResult2, theExecutionContext) == true) { thePrintWriter.print("theResult1 is equal to theResult2"); thePrintWriter.println(); thePrintWriter.print("theContextNode->getNodeName() == \""); thePrintWriter.print(theContextNode->getNodeName()); thePrintWriter.print("\" theContextNode->getNodeValue() == \""); thePrintWriter.print(theContextNode->getNodeValue()); thePrintWriter.println("\""); } } } } } return fError; }
bool TestAxisResult( XPathProcessor& theXPathProcessor, XPathEnvSupport& theXPathEnvSupport, DOMSupport& theDOMSupport, XMLParserLiaison& theLiaison, XPathFactory& theXPathFactory, const XalanDOMString& theXMLFileURL, const XalanDOMString& theXSLFileURL, PrintWriter& thePrintWriter, XPathExecutionContext& theExecutionContext) { bool fError = false; XalanDocument* const theXMLDocument = ParseXML(theLiaison, theXMLFileURL); MemoryManagerType& theMemoryManager = theExecutionContext.getMemoryManager(); if (theXMLDocument != 0) { XalanDOMString theContextNodeMatchPattern(theMemoryManager); XalanDOMString theXPathString(theMemoryManager); if (GetXSLInput(theLiaison, theXSLFileURL, theContextNodeMatchPattern, theXPathString, theMemoryManager) == true) { XalanNode* const theContextNode = FindContextNode(theXPathProcessor, theXPathEnvSupport, theDOMSupport, theXPathFactory, theXMLDocument, theContextNodeMatchPattern, thePrintWriter, theExecutionContext); if (theContextNode != 0) { XalanElement* const theNamespaceContext = 0; ElementPrefixResolverProxy thePrefixResolver(theNamespaceContext, theXPathEnvSupport, theDOMSupport); NodeRefList theContextNodeList(theMemoryManager); XPath* const theXPath = theXPathFactory.create(); XPathConstructionContextDefault theXPathConstructionContext(theMemoryManager); XPathGuard theGuard(theXPathFactory, theXPath); theXPathProcessor.initXPath(*theXPath, theXPathConstructionContext, theXPathString, thePrefixResolver); bool fDump = false; if (fDump == true) { thePrintWriter.println(); thePrintWriter.println(); theXPath->getExpression().dumpOpCodeMap(thePrintWriter); thePrintWriter.println(); theXPath->getExpression().dumpTokenQueue(thePrintWriter); thePrintWriter.println(); thePrintWriter.println(); } const XObjectPtr theResult = theXPath->execute(theContextNode, thePrefixResolver, theContextNodeList, theExecutionContext); try { assert(theResult.null() == false); const NodeRefListBase& theResultList = theResult->nodeset(); const unsigned int theLength = theResultList.getLength(); if (theLength == 0) { thePrintWriter.println("<out/>"); } else { thePrintWriter.print("<out>"); for (unsigned int i = 0; i < theLength; i++) { thePrintWriter.print(theResultList.item(i)->getNodeName()); thePrintWriter.print(" "); } thePrintWriter.println("</out>"); } } catch(...) { thePrintWriter.print("Execution of XPath "); thePrintWriter.print(theXPathString); thePrintWriter.println(" failed!"); } } } } theLiaison.reset(); return fError; }
XalanNode* FindContextNode( XPathProcessor& theXPathProcessor, XPathEnvSupport& theXPathEnvSupport, DOMSupport& theDOMSupport, XPathFactory& theXPathFactory, XalanDocument* theDocument, const XalanDOMString& theContextNodeMatchPattern, PrintWriter& thePrintWriter, XPathExecutionContext& theExecutionContext) { XalanNode* theResult = 0; MemoryManagerType& theMemoryManager = theExecutionContext.getMemoryManager(); XPath* const theXPath = theXPathFactory.create(); XPathConstructionContextDefault theXPathConstructionContext; XPathGuard theGuard( theXPathFactory, theXPath); XalanElement* theNamespaceContext = 0; ElementPrefixResolverProxy thePrefixResolver(theNamespaceContext, theXPathEnvSupport, theDOMSupport); NodeRefList theContextNodeList(theMemoryManager); const XObjectPtr theXObject = ExecuteXPath( theXPathProcessor, theXPathConstructionContext, *theXPath, theContextNodeMatchPattern, theDocument, thePrefixResolver, theContextNodeList, theExecutionContext); try { assert(theXObject.null() == false); const NodeRefListBase& theResultList = theXObject->nodeset(); if (theResultList.getLength() == 0) { thePrintWriter.print("FindContextNode: Unable to find context node using select \""); thePrintWriter.print(theContextNodeMatchPattern); thePrintWriter.println("\"."); thePrintWriter.println("FindContextNode: No nodes matched the pattern."); } else if (theResultList.getLength() != 1) { thePrintWriter.print("FindContextNode: Unable to find context node using select \""); thePrintWriter.print(theContextNodeMatchPattern); thePrintWriter.println("\"."); thePrintWriter.println("FindContextNode: More than one node matched the pattern."); } else { theResult = theResultList.item(0); } } catch(...) { thePrintWriter.print("FindContextNode: Error executing match pattern \""); thePrintWriter.print(theContextNodeMatchPattern); thePrintWriter.println("\"."); } return theResult; }
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); } } }