TEST_F(XPathAcceptanceTest, variables) { XPath xpath = compile("$variable"); xpath.bind_variable("variable", 5.2); ASSERT_DOUBLE_EQ(5.2, xpath.number()); }
void PersistenceModule::instructionDrop ( __XProcHandlerArgs__ ) { XPath selectXPath ( getXProcessor(), item, xem_pers.select() ); Document& doc = selectXPath.evalElement().getDocument(); if ( item.hasAttr ( xem_pers.branchRevId() ) ) { String branchRevStr = item.getEvaledAttr ( getXProcessor(), xem_pers.branchRevId() ); BranchRevId branchRevId = BranchManager::parseBranchRevId ( branchRevStr.c_str() ); if ( ! branchRevId.branchId || ! branchRevId.revisionId ) { throwException ( Exception, "Invalid branch and revision id '%s'\n", branchRevStr.c_str() ); } Log_Pers ( "[XEM:BRANCH] Dropping alter revision [%llu:%llu]\n", _brid(doc.getBranchRevId()) ); NotImplemented ( "We shall schedule revision removal here !\n" ); #if 0 // store.dropRevisions ( branchRevId.branchId, branchRevId.revisionId, branchRevId.revisionId ); persistentDocument = store.createPersistentDocument ( branchRevId.branchId, branchRevId.revisionId, Document_Read ); persistentDocument->scheduleRevisionForRemoval (); persistentDocument->release (); #endif return; } Log_Pers ( "[XEM:BRANCH] Dropping current revision [%llu:%llu]\n", _brid(doc.getBranchRevId()) ); doc.scheduleRevisionForRemoval (); }
static void xemInstructionSetDocument ( __XProcHandlerArgs__ ) { if ( ! item.hasAttr(xem.href() ) ) { throwXemProcessorException ( "Instruction xem:set-document has no attribute xem:href\n" ); } if ( ! item.hasAttr(xem.select() ) ) { throwXemProcessorException ( "Instruction xem:set-document has no attribute xem:select\n" ); } String href = item.getEvaledAttr ( xproc, currentNode, xem.href() ); XPath selectXPath ( item, xem.select() ); NodeSet document; selectXPath.eval ( xproc, document, currentNode ); if ( ! document.isScalar() ) { throwXemProcessorException ( "Instruction xem:set-document : xem:select '%s' returns a non-scalar result !\n", item.getAttr (xem.select() ).c_str() ); } if ( ! document.front().isElement() ) { throwXemProcessorException ( "Instruction xem:set-document : xem:select '%s' returns a non-element result !\n", item.getAttr (xem.select() ).c_str() ); } ElementRef rootDocument = document.front().toElement(); xproc.setDocument ( href, rootDocument ); }
void PersistenceModule::instructionReopen ( __XProcHandlerArgs__ ) { XPath selectXPath ( getXProcessor(), item, xem_pers.select() ); Document& doc = selectXPath.evalElement().getDocument(); if ( doc.isWritable() ) { throwException ( Exception, "Current Revision is writable, you should commit it before reopen.\n" ); } doc.reopen ( getXProcessor() ); }
void PersistenceModule::instructionFork ( __XProcHandlerArgs__ ) { XPath selectXPath ( getXProcessor(), item, xem_pers.select() ); Document& doc = selectXPath.evalElement().getDocument(); if ( doc.isWritable() ) { throwException ( Exception, "Current Revision is writable, you should commit it before forking.\n" ); } String branchName = item.getEvaledAttr ( getXProcessor(), xem_pers.name() ); doc.fork ( getXProcessor(), branchName, BranchFlags_MayIndexNameIfDuplicate ); }
void PersistenceModule::instructionRenameBranch ( __XProcHandlerArgs__ ) { XPath selectXPath ( getXProcessor(), item, xem_pers.select() ); Document& doc = selectXPath.evalElement().getDocument(); BranchId branchId = doc.getBranchRevId().branchId; String branchName = item.getEvaledAttr ( getXProcessor(), xem_pers.name() ); Log_Pers ( "[XEM-BRANCH] Rename branch %llu to '%s'\n", branchId, branchName.c_str() ); getXProcessor().getStore().getBranchManager().renameBranch ( branchId, branchName.c_str() ); }
TEST_F(XPathAcceptanceTest, location_paths_apply_to_variables) { Element *parent = doc.new_element("parent"); Element *child = add_child(parent, "child"); XPath xpath = compile("$variable/child"); Nodeset variable_value; variable_value.add(parent); xpath.bind_variable("variable", variable_value); ASSERT_THAT(xpath.nodeset(), ElementsAre(child)); }
/// copy matching tree nodes using the given XPath filter expression bool XMLNode::filter(const XPath& xpath, XMLNode& target) const { XMLNode* ret = filter(xpath.begin(), xpath.end()); if (ret) { // move returned nodes to target node target._children.move(ret->_children); target._attributes = ret->_attributes; delete ret; return true; } else return false; }
void XFileManager::SetDataDirPath(const XPath& dataDirPath) { if (dataDirPath.IsRelPath()) { size_t relNodeCount; XPath leafPath; dataDirPath.GetLeafExceptRelNodes(relNodeCount, leafPath); m_execDirAbsPath.GetBranchExceptLeafs(relNodeCount, m_dataDirAbsPath); m_dataDirAbsPath.AppendPath(leafPath); } else { m_dataDirAbsPath.AssignPath(m_execDirAbsPath); m_dataDirAbsPath.AppendPath(dataDirPath); } }
void XFileManager::SetExecFilePath(const XPath& execFilePath) { char execFileAbsPathChars[PATH_MAX]; x_verify(realpath(execFilePath.GetChars(), execFileAbsPathChars), "CHECK_EXEC_PATH"); // TODO: x_vertifyf m_execFileAbsPath.AssignXStr(execFileAbsPathChars); m_execFileAbsPath.SplitBranchAndLeaf(m_execDirAbsPath, m_execFileName); }
XALAN_CPP_NAMESPACE_USE XERCES_CPP_NAMESPACE_USE const XObjectPtr ExecuteXPath( XPathProcessor& theXPathProcessor, XPathConstructionContext& theXPathConstructionContext, XPath& theXPath, const XalanDOMString& theXPathString, XalanNode* theContextNode, const PrefixResolver& thePrefixResolver, const NodeRefListBase& theContextNodeList, XPathExecutionContext& theExecutionContext) { theXPathProcessor.initXPath( theXPath, theXPathConstructionContext, theXPathString, thePrefixResolver); const XObjectPtr theResult = theXPath.execute(theContextNode, thePrefixResolver, theContextNodeList, theExecutionContext); return theResult; }
void XPath::evalFunctionKeyGet ( ElementMultiMapRef& map, XPath& useXPath, NodeSet& resultNodeSet, String& value ) { __ui64 hash = SKMapRef::hashString ( value ); Log_EvalKey ( "Computed value : '%s', hash='%llx'\n", value.c_str(), hash ); for ( SKMultiMapRef::multi_iterator miter ( map, hash ); miter ; miter++ ) { Log_EvalKey ( "Found iter %llx, val=%llx\n", miter.getHash(), miter.getValue() ); if ( miter.getHash() != hash ) { Log_EvalKey ( "Diverging keys : %llx != %llx\n", miter.getHash(), hash ); break; } ElementRef foundElt = map.get ( miter ); Log_EvalKey ( "Found elt=0x%llx\n", foundElt.getElementId() ); // AssertBug ( foundElt.getElementId(), "Null elementId ! Element was deleted ?\n" ); NodeSet foundValue; useXPath.eval ( foundValue, foundElt ); for ( NodeSet::iterator valiter ( foundValue ) ; valiter ; valiter++ ) { String eltValue = valiter->toString(); Log_EvalKey ( "Found node 0x%llx:%s, eltValue='%s'\n", foundElt.getElementId(), foundElt.getKey().c_str(), eltValue.c_str() ); if ( eltValue == value ) { resultNodeSet.pushBack ( foundElt, true ); Log_EvalKey ( "Matches !\n" ); } } } }
void PersistenceModule::instructionMerge ( __XProcHandlerArgs__ ) { XPath selectXPath ( getXProcessor(), item, xem_pers.select() ); Document& doc = selectXPath.evalElement().getDocument(); bool keepBranch = false; try { doc.merge ( getXProcessor(), keepBranch ); } catch ( Exception* e ) { detailException ( e, "xem:merge : could not merge branch.\n" ); throw ( e); } doc.scheduleBranchForRemoval (); }
void PersistenceModule::instructionCommit ( __XProcHandlerArgs__ ) { XPath selectXPath ( getXProcessor(), item, xem_pers.select() ); Document& doc = selectXPath.evalElement().getDocument(); if ( !doc.isWritable() ) { AssertBug ( !doc.isLockedWrite(), "Document not writable, but locked write ?\n" ); Warn ( "Document '%s' (%llx:%llx) not writable !\n", doc.getRole().c_str(), _brid(doc.getBranchRevId()) ); return; throwException ( Exception, "Document not writable !\n" ); } if ( !doc.isLockedWrite() ) { doc.lockWrite(); } doc.commit ( getXProcessor() ); }
void XPath::evalFunctionKeyGet ( __XPath_Functor_Args ) { KeyId keyNameId = evalStepAsKeyId ( node, step->functionArguments[0] ); __evalArgNodeSet(1); Log_EvalKey ( "xsl:key : expression '%s'\n", expression ); XPath matchXPath ( xproc ); XPath useXPath ( xproc ); XPath scopeXPath(xproc); getXProcessor().getXPathKeyExpressions(keyNameId, matchXPath,useXPath); ElementMultiMapRef map = node.getDocument().getKeyMapping ( keyNameId ); if ( ! map ) { map = node.getDocument().createKeyMapping ( keyNameId ); AssertBug ( map, "Could not create SKMultiMapRef !\n" ); Log_EvalKey ( "Building for key '%x'\n", keyNameId ); ElementRef baseElement = node.getRootElement (); #if 0 if ( instructKey.findAttr ( __builtinKey(xsl.base) ) ) { throwXPathException ( "Invalid xsl:base attribute set !\n" ); XPath baseXPath ( instructKey, __builtinKey(xsl.base) ); Log_EvalKey ( "xsl:base : expression '%s'\n", baseXPath.expression ); Log_EvalKey ( "xsl:base - before : base : %llx:%s\n", baseElement.getElementId(), baseElement.getKey().c_str() ); baseElement = baseXPath.evalElement ( baseElement ); Log_EvalKey ( "xsl:base - after : base : %llx:%s\n", baseElement.getElementId(), baseElement.getKey().c_str() ); } #endif evalFunctionKeyBuild ( baseElement, map, matchXPath, useXPath, scopeXPath, 0 ); } evalFunctionKeyGet ( map, useXPath, result, res1 ); }
int main() { char* fileName = new char[MAX_CHAR_SIZE]; char* cmdBuf = new char[MAX_CHAR_SIZE]; XPath Xpath; XMLParser XParser; XMLNode* XpathRoute = new XMLNode; while(1) { cout << "Input FileName(quit) : "; cin >> fileName; if(!strcmp(fileName, "quit")) { delete[] fileName; delete[] cmdBuf; delete XpathRoute; return 0; } else if(!XParser.parser(fileName, XpathRoute)) break; } while(1) { cout << "cmd : "; cin >> cmdBuf; if(!strcmp(cmdBuf, "quit")) break; else Xpath.XPathCmdParser(cmdBuf, XpathRoute); } delete[] fileName; delete[] cmdBuf; delete XpathRoute; return 0; }
XObjectPtr XPathEvaluator::evaluate( DOMSupport& domSupport, XalanNode* contextNode, const XPath& xpath, const PrefixResolver& prefixResolver, XPathEnvSupport& envSupport) { // Reset these, in case we've been here before... m_executionContext->reset(); m_xobjectFactory->reset(); // Set up the connections between the execution context and // the provided support objects... m_executionContext->setXPathEnvSupport(&envSupport); m_executionContext->setXObjectFactory(m_xobjectFactory.get()); m_executionContext->setDOMSupport(&domSupport); // OK, evaluate the expression... const XObjectPtr theResult( xpath.execute( contextNode, prefixResolver, *m_executionContext.get())); // Break the connectons we set... m_executionContext->setXPathEnvSupport(0); m_executionContext->setXObjectFactory(0); m_executionContext->setDOMSupport(0); return theResult; }
TEST_F(XPathAcceptanceTest, invalid_function_throws_exception) { XPath xpath = compile("bogus()"); ASSERT_THROW(xpath.number(), UnknownXPathFunctionException); }
void XPath::evalFunctionKeyBuild ( ElementRef& baseElement, ElementMultiMapRef& map, XPath& matchXPath, XPath& useXPath, XPath& scopeXPath, KeyId mapId ) { bool recursive = true; // Warn !! Log_EvalKey ( "evalFunctionKeyBuild(baseElement=%s, match=%s, use=%s, scope=%s\n", baseElement.getKey().c_str(), matchXPath.expression, useXPath.expression, scopeXPath.expression); if ( ! recursive ) { Warn ( "Building key in a non-recursive mode ! This is against XSL specifications !\n" ); } if ( ! baseElement.getChild() ) { Log_EvalKey ( "Base element has no children !\n" ); return; } ElementRef current = baseElement; Log_EvalKey ( "Building Key !\n" ); Log_EvalKey ( "baseElement = '%s'\n", baseElement.getKey().c_str() ); Log_EvalKey ( "baseElement = '%s'\n", baseElement.generateVersatileXPath().c_str() ); __ui64 iterated = 0, found = 0; bool currentMatches; while ( true ) { Log_EvalKey ( "[At element %s (0x%llx:%x/%s), matching '%s' ?\n", current.generateVersatileXPath().c_str(), current.getElementId(), current.getKeyId(), current.getKey().c_str(), matchXPath.expression ); currentMatches = false; iterated++; if ( matchXPath.matches ( current ) ) { Log_EvalKey ( "Matches !\n" ); currentMatches = true; found++; if ( map ) { map.insert ( current, useXPath ); } else { NodeSet scopeNodeSet; scopeXPath.eval ( scopeNodeSet, current ); if ( scopeNodeSet.size() == 1 && scopeNodeSet.front().isElement() ) { ElementRef scopeElement = scopeNodeSet.toElement(); ElementMultiMapRef currentMap = scopeElement.findAttr ( mapId, AttributeType_SKMap ); if ( ! currentMap ) { Info ( "New skMap at '%s'\n", scopeElement.generateVersatileXPath().c_str() ); currentMap = scopeElement.addSKMap ( mapId, SKMapType_ElementMultiMap ); } Log_EvalKey ( "Inserting '%s'\n", current.generateVersatileXPath().c_str() ); currentMap.insert ( current, useXPath ); } else { Info ( "Silently ignoring '%s' : scope did not eval to an Element.\n", current.generateVersatileXPath().c_str() ); } } } if ( current.getChild() && ( !currentMatches || recursive ) ) { Log_EvalKey ( "Don't match, but has children.\n" ); current = current.getChild(); continue; } else { Log_EvalKey ( "Don't match, but no has child.\n" ); } while ( ! current.getYounger() ) { AssertBug ( current != baseElement, "How did I get there ?\n" ); current = current.getFather(); if ( ! current ) { throwException ( Exception, "Preliminary end of element !\n" ); } AssertBug ( current, "current had no father !\n" ); if ( current == baseElement ) { Log_EvalKey ( "Indexing finished : iterated over %llu, found %llu.\n", iterated, found ); return; } } current = current.getYounger (); } }
TEST_F(XPathAcceptanceTest, relational) { XPath xpath = compile("1.0 >= 2.1"); ASSERT_EQ(false, xpath.boolean()); }
TEST_F(XPathAcceptanceTest, equality) { XPath xpath = compile("1.3 != '1.3'"); ASSERT_EQ(false, xpath.boolean()); }
TEST_F(XPathAcceptanceTest, boolean_logic) { XPath xpath = compile("true() and false()"); ASSERT_EQ(false, xpath.boolean()); }
bool TestBooleanResult( XPathProcessor& theXPathProcessor, XPath& theXPath, XPathConstructionContext& theXPathConstructionContext, const XalanDOMString& theXPathString, PrintWriter& thePrintWriter, bool theExpectedResult, XalanNode* theContextNode, const PrefixResolver& thePrefixResolver, const NodeRefListBase& theContextNodeList, XPathExecutionContext& theExecutionContext) { bool fError = false; const XObjectPtr theResult = ExecuteXPath( theXPathProcessor, theXPathConstructionContext, theXPath, theXPathString, theContextNode, thePrefixResolver, theContextNodeList, theExecutionContext); bool fDump = false; if (fDump == true) { thePrintWriter.println(); thePrintWriter.println(); theXPath.getExpression().dumpOpCodeMap(thePrintWriter); thePrintWriter.println(); theXPath.getExpression().dumpTokenQueue(thePrintWriter); thePrintWriter.println(); thePrintWriter.println(); } thePrintWriter.print("Execution of XPath "); thePrintWriter.print(theXPathString); if (theResult->boolean() == theExpectedResult) { thePrintWriter.println(" succeeded."); thePrintWriter.print("The result was "); thePrintWriter.print(theResult->boolean()); thePrintWriter.println("."); } else { fError = true; thePrintWriter.println(" failed!"); thePrintWriter.print("The expected result was \""); thePrintWriter.print(theExpectedResult); thePrintWriter.println("\"."); thePrintWriter.print("The actual result was \""); thePrintWriter.print(theResult->boolean()); thePrintWriter.println("\"."); } return fError; }
TEST_F(XPathAcceptanceTest, unary_negation) { XPath xpath = compile("2 - -2"); ASSERT_DOUBLE_EQ(4.0, xpath.number()); }
TEST_F(XPathAcceptanceTest, multiplicitive_math_operations) { XPath xpath = compile("5 mod 2 div 3 * 2"); ASSERT_DOUBLE_EQ(2/3.0, xpath.number()); }
TEST_F(XPathAcceptanceTest, additive_math_operations) { XPath xpath = compile("1 - 2 + 3"); ASSERT_DOUBLE_EQ(2.0, xpath.number()); }
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; }