You have to declare the namespace prefixes in the static context. You're using the IndependentContext class, which has a method declareNamespace(prefix, uri) for this purpose. The prefix you use doesn't have to match any prefix in the source document, so long as the URI matches.

(There are actually two classes called XPathEvaluator in packages xpath and sxpath, for legacy reasons. I'm not sure which you are using, but I think the answer is the same either way.)

You are using some pretty low-level Saxon interfaces here and it can be hard to find your way around them. I think you will find that using the s9api interface would be much cleaner.

The exception looks like:
Prefix testPrefix has not been declared
net.sf.saxon.trans.XPathException: Prefix testPrefix has not been declared
    at net.sf.saxon.expr.ExpressionParser.grumble(
    at net.sf.saxon.expr.ExpressionParser.makeNameCode(

You shouldn't really be generating a stack trace for an XPathException, unless you are interested in the Saxon internal code for some reason. The XPathException is designed to be caught, and it should tell you all you need to know about what's wrong with your XPath expression.
I should note that these name-spaces prefixes / URLs are declared in the XML fragment.
But I *assume* that the ExpressionParser does not retrieve the name-spaces from the XML document before interpreting the query.
That's correct. If you want to use the same prefix/uri bindings as appear in the source document, you need to process the source document, discover what prefixes are in use, and then bind them in the static context for the XPath expression. For example you could execute the expression "distinct-values(//namespace::*/name())" to discover all the prefixes in use.
So I have to provide the name-spaces somehow to the ExpressionParser.
Is there a way to retrieve the name-spaces available in the Source and place them on the xPathEvaluator?

As a parenthesis, I have tried the AxisIterator approach like below, but I get NullPointerExceptions:
   AxisIterator iterator = node.iterateAxis(Axis.NAMESPACE);
   // String string = iterator.atomize().getStringValue(); this throws NullPointerException
   String string = iterator.getStringValue().toString(); // this throws, too
If you look at the spec for AxisIterator, you'll see that calling atomize() or getStringValue() are defined to throw an NPE if the iterator isn't positioned on any node. When an iterator is first created, it isn't positioned on any node until you call next(), which moves it to the first selected node. Again, this is a very low-level interface. The way to get the prefixes and namespaces at this level is something like this:

Map<String, String> namespaces = new HashMap<String, String>();
AxisIterator iterator = element.iterateAxis(Axis.NAMESPACE);
NodeInfo ns;
while (ns = != null) {
  namespaces.put(ns.getLocalPart(), ns.getStringValue());

Michael Kay

Perhaps I should load the XML fragment in a different way? Please see below how the XML fragment is loaded.

To be a bit more precise, my code looks like the one below (reduced for simplicity):
   // build the context, evaluator and expression
   IndependentContext context = new IndependentContext();
   XPathEvaluator xPathEvaluator = new XPathEvaluator();
   xPathExpression = xPathEvaluator.createExpression(xPathQuery);

   // load the XML document (which is stored in xmlDocument)
   StreamSource source = new StreamSource(new ByteArrayInputStream(xmlDocument.getBytes("UTF-8")));
   Configuration config = xPathEvaluator.getConfiguration();
    NodeInfo node = config.buildDocument(source);

   // query the input node
   xPathExpression = xPathEvaluator.createExpression(xPathQuery);  <--- here is where the "Prefix has not been declared" exception occurs.
   List<NodeInfo> resultNodeList = (List<NodeInfo>) (List< ? >) xPathExpression.evaluate(node);

Thanks in advance,

The demand for IT networking professionals continues to grow, and the
demand for specialized networking skills is growing even more rapidly.
Take a complimentary Learning@Cisco Self-Assessment and learn 
about Cisco certifications, training, and career opportunities.

saxon-help mailing list archived at