Garret Wilson
Garret Wilson

Reputation: 21446

Associate XPath namespace prefix in Saxon 12

I'm wanting to use XPath with Saxon 12 using Java 17, and I'm trying to associate namespaces with prefixes for my XPath expression.

In the standard JAXP API I'd do something like this:

XPathFactory.newInstance().newXPath().setNamespaceContext(…);

Then I would create a special namespace context that would send back namespace URIs for prefixes. It's a little unwieldy, but I've long created wrapper classes which allow these mappings to be set easily.

How do I do that with Saxon? The documentation says:

In XPath 1.0, an unprefixed name in an XPath expression was defined to match no-namespace elements in the source document. If the source document uses a namespace (even if it's the default namespace, used with no prefix), then the corresponding names in the XPath expression need to be prefixed.

XPath 2.0 introduced the idea of a default namespace for elements and types, allowing you to declare that unprefixed element names in the XPath expression refer to some specific namespace in the source document. This isn't supported in the JAXP API (which was never updated to handle XPath 2.0), but it's supported in the Saxon APIs: binding the zero-length prefix to a namespace URI has the effect of making that the default namespace for element and type names.

Saxon (from 11.0) goes a step further and allows you to declare an unprefixed element matching policy that determines how unprefixed element names are handled.

That all sounds nice and apparently Saxon offers everything that JAXP does and more, but I'm not immediately seeing where to set namespace mappings before evaluating my XPath expression.

Upvotes: 3

Views: 160

Answers (1)

Michael Kay
Michael Kay

Reputation: 163468

In the s9api interface, it's XPathCompiler.declareNamespace(prefix, uri).

That gives you straightforward prefix-to-uri mappings, and if you use the prefix "", then it sets the default namespace for unprefixed element names in your XPath expression.

There's also XPathCompiler.setUnprefixedElementMatchingPolicy() which allows you to set some other options for matching unprefixed element names.

One option is to allow unprefixed element names to match by local name only, ignoring the namespace. That's often handy for ad-hoc XPath queries (very few documents actually have two elements with the same local name and different namespaces).

Another option is to let unprefixed names match elements if they are in either the default namespace or in no namespace. That's intended specifically for HTML/XHTML, and is provided mainly because it has a similar effect to the "wilful violation" (their words) of the XPath 1.0 specification adopted by the WhatWG in HTML5.

Upvotes: 1

Related Questions