You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by Richard Zschech <ri...@cqrdata.com> on 2002/11/20 14:18:34 UTC

XPathEvaluator namespace prefix issues

Hi,

I'm having a problem using the 
org.apache.xpath.domapi.XPathEvaluatorImpl with namespace prefixes in my 
xpath expression.
An example xpath I have is "dyn:map(., '.')" which dosent do much but it 
relies on the exslt extensions.

I have made a custom namespace resolver which maps the standard exslt 
prefixes to their namespaces and a test program as follows:




import java.io.StringReader;
import org.xml.sax.InputSource;

import org.w3c.dom.Node;
import org.w3c.dom.Document;
import org.w3c.dom.xpath.XPathResult;
import org.w3c.dom.xpath.XPathException;
import org.w3c.dom.xpath.XPathEvaluator;
import org.w3c.dom.xpath.XPathExpression;
import org.w3c.dom.xpath.XPathNSResolver;

import javax.xml.parsers.DocumentBuilderFactory;

// Need to extend org.apache.xpath.domapi.XPathNSResolverImpl to prevent 
class casts in the xpath evaluator
public class XPathTest extends 
org.apache.xpath.domapi.XPathNSResolverImpl implements XPathNSResolver {
     public static void main(String[] args) throws Exception {
       org.apache.xalan.Version.main(null);
       XPathEvaluator xpathEvaluator = new 
org.apache.xpath.domapi.XPathEvaluatorImpl();
       DocumentBuilderFactory documentBuilderFactory = 
DocumentBuilderFactory.newInstance();
       documentBuilderFactory.setNamespaceAware(true);
             Document doc = 
documentBuilderFactory.newDocumentBuilder().parse(new InputSource(new 
StringReader("<foo/>")));
             try {
           System.out.println("Trying with no namespace resolver");
           Object result = xpathEvaluator.evaluate("dyn:map(., '.')", 
doc, null, XPathResult.ANY_TYPE, null);
           System.out.println(result);
       }
       catch(Exception e) {
           System.out.println("I expected this to fail");
           e.printStackTrace();
       }

       try {
           System.out.println();
           System.out.println("Trying with my namespace resolver");
           Object result = xpathEvaluator.evaluate("dyn:map(., '.')", 
doc, new XPathTest(), XPathResult.ANY_TYPE, null);
           System.out.println(result);
       }
       catch(Exception e) {
           System.out.println("I cant work out why this failed");
           e.printStackTrace();
       }
   }
         private XPathTest() {
       super(null);
   }
     // these methods are the ones called by the xpath engine
   public String getNamespaceForPrefix(String prefix) {
       return lookupNamespaceURI(prefix);
   }
   public String getNamespaceForPrefix(String prefix, Node 
namespaceContext) {
       return lookupNamespaceURI(prefix);
   }
     // do the actual namespace lookup
   public String lookupNamespaceURI(String prefix) {
       System.out.println("lookupNamespaceURI " + prefix);
             if(prefix.equals("date")) {
           return "http://exslt.org/dates-and-times";
       }
       else if(prefix.equals("dyn")) {
           return "http://exslt.org/dynamic";
       }
       else if(prefix.equals("exsl")) {
           return "http://exslt.org/common";
       }
       else if(prefix.equals("func")) {
           return "http://exslt.org/functions";
       }
       else if(prefix.equals("math")) {
           return "http://exslt.org/math";
       }
       else if(prefix.equals("regexp")) {
           return "http://exslt.org/regular-expressions";
       }
       else if(prefix.equals("set")) {
           return "http://exslt.org/sets";
       }
       else if(prefix.equals("str")) {
           return "http://exslt.org/strings";
       }
       else {
           return null;
       }
   }
}



I try to evaluate the xpath with no name space resolver and it fails as 
expected:


Trying with no namespace resolver
I expected this to fail
org.w3c.dom.DOMException: Unable to resolve prefix with null prefix 
resolver.
       at 
org.apache.xpath.domapi.XPathEvaluatorImpl$DummyPrefixResolver.getNamespaceForPrefix(XPathEvaluatorImpl.java:115) 

       at 
org.apache.xpath.domapi.XPathEvaluatorImpl$DummyPrefixResolver.getNamespaceForPrefix(XPathEvaluatorImpl.java:125) 

       at org.apache.xpath.compiler.Lexer.mapNSTokens(Lexer.java:625)
       at org.apache.xpath.compiler.Lexer.tokenize(Lexer.java:303)
       at org.apache.xpath.compiler.Lexer.tokenize(Lexer.java:134)
       at 
org.apache.xpath.compiler.XPathParser.initXPath(XPathParser.java:155)
       at org.apache.xpath.XPath.<init>(XPath.java:202)
       at org.apache.xpath.XPath.<init>(XPath.java:238)
       at 
org.apache.xpath.domapi.XPathEvaluatorImpl.createExpression(XPathEvaluatorImpl.java:199) 

       at 
org.apache.xpath.domapi.XPathEvaluatorImpl.evaluate(XPathEvaluatorImpl.java:291) 

       at XPathTest.main(XPathTest.java:30)


Then with my namespace resolver:

Trying with my namespace resolver
lookupNamespaceURI dyn
I cant work out why this failed
org.w3c.dom.xpath.XPathException: Unknown error in XPath
       at 
org.apache.xpath.domapi.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:208) 

       at 
org.apache.xpath.domapi.XPathEvaluatorImpl.evaluate(XPathEvaluatorImpl.java:293) 

       at XPathTest.main(XPathTest.java:41)


In my actual usage rather then the test above I have also got the 
following probably related exception:

org.w3c.dom.xpath.XPathException: java.lang.NoSuchMethodException: For 
extension function, could not find method 
org.apache.xpath.axes.WalkingIterator.map([ExpressionContext,] #STRING).
       at 
org.apache.xpath.domapi.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:208) 

       at 
org.apache.xpath.domapi.XPathEvaluatorImpl.evaluate(XPathEvaluatorImpl.java:293) 


Im guessing the xpath engine is looking in the wrong class for the map 
method.


Do I need to do any more to set up the 
org.apache.xpath.domapi.XPathEvaluatorImpl object before calling the 
evaluate method with the correct namespace resolver?

Thanks for any help in advance,

 From Richard.