Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no XPath syntax for namespace-qualified nodes?

Some of the nodes in an XML document have namespaces, specified with a defined prefix.

It is possible to specify local-name() in XPath 1.0 and so ignore namespaces.

However, I want to enable the writer of the XPath to find nodes using their full namespace-qualified name as an identifier.

The recommended way is to add namespace declarations in the invoking code (in my case, Java). But this means that the person writing Xpath does not have the ability to work with namespaces!

How do we find nodes by their fully qualified names using pure XPath?

like image 990
Joshua Fox Avatar asked Aug 14 '11 12:08

Joshua Fox


People also ask

What is namespace node in XPath?

XPath queries are aware of namespaces in an XML document and can use namespace prefixes to qualify element and attribute names. Qualifying element and attribute names with a namespace prefix limits the nodes returned by an XPath query to only those nodes that belong to a specific namespace.

What is XPath expression in XML?

XPath uses path expressions to select nodes or node-sets in an XML document. These path expressions look very much like the expressions you see when you work with a traditional computer file system. XPath expressions can be used in JavaScript, Java, XML Schema, PHP, Python, C and C++, and lots of other languages.

How do you create a namespace in XML?

XML Namespaces - The xmlns Attribute When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax. xmlns:prefix="URI".


3 Answers

Not sure what you meant by "as an identifier".

How do we find nodes by their fully qualified names using pure XPath?

In XPath 1.0, by using local-name() and namespace-uri(), e.g.

"*[local-name() = 'foo' and namespace-uri() = 'http://my.org/ns/2.0']"

In XPath 2.0, there is a richer set of functions related to namespaces, e.g. namespace-uri-from-QName(). But I'm not sure they improve on the above for what you want.

like image 171
LarsH Avatar answered Oct 15 '22 02:10

LarsH


XPath 3.0, which is currently in working draft status, will include a literal expression for URI qualified QNames allowing to directly specify the namespace uri.

Here are some examples of EQNames:

  • pi is a lexical QName without a namespace prefix.
  • math:pi is a lexical QName with a namespace prefix.
  • "http://www.w3.org/2005/xpath-functions/math":pi specifies the namespace URI using a URILiteral; it is not a lexical QName.

I think Saxon 9.3 includes a preview implementation of xpath 3.0 which should be usable through the java api.

like image 27
Jörn Horstmann Avatar answered Oct 15 '22 04:10

Jörn Horstmann


You can use namespaces during your XPath queries. In Java, what you need to provide is an implementation of NamespaceContext if you also want to use prefixes in those queries instead of the fully qualified namespace all the time. Just add an instance of NamespaceContext to your XPath - I'll assume you use the standard JDK implementation - but the concept is applicable to Jaxen or others as well.

Then you can perform queries such as //customns:Element.

If you don't or can't use a NamespaceContext (for whatever reason) then the only solution seems to be using the local-name and namespace-uri functions:

Document doc = ...;
XPath xp = XPathFactory.newInstance().newXPath();
String name = "Element";
String ns = "http://www.custom.org/#";
String expr = "//*[local-name() = '"+name+" and namespace-uri() = '"+ns+"']";
Node node = ((NodeList)xp.evaluate(expr, doc, XPathConstants.NODESET)).item(0);
like image 31
emboss Avatar answered Oct 15 '22 03:10

emboss