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.