TEST_F(XPathAcceptanceTest, variables)
{
    XPath xpath = compile("$variable");

    xpath.bind_variable("variable", 5.2);
    ASSERT_DOUBLE_EQ(5.2, xpath.number());
}
Beispiel #2
0
  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 ();
  }
Beispiel #3
0
  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 );
  }
Beispiel #4
0
 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() );
 }
Beispiel #5
0
 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 );
 }
Beispiel #6
0
  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));
}
Beispiel #8
0
 /// 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;
}
Beispiel #9
0
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);
    }
}
Beispiel #10
0
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;
}
Beispiel #12
0
  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" );
              }
            
          }
      }
  }  
Beispiel #13
0
  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 ();
  }  
Beispiel #14
0
 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() );
 }
Beispiel #15
0
  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 );
  }
Beispiel #16
0
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);
}
Beispiel #19
0
  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());
}
Beispiel #27
0
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);

}
Beispiel #28
0
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;
}