Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declare namespaces within XPath expression

My application needs to evaluate XPath expression against some XML data. Expression is provided by user at runtime. So, I cannot create XmlNamespaceManager to pass to XPathEvaluate because I don't know prefixes and namespaces at compile time.

Is there any possibility to specify namespaces declaration within xpath expression?


Answers to comments:

  1. XML data has one default namespace but there can be nested elements with any namespaces. User knows namespaces of the data he works with.
  2. User-provided xpath expression is to be evaluated against many XML documents, and every document can have its own prefixes for the same namespaces.
like image 946
Anthony Serdyukov Avatar asked Feb 01 '11 10:02

Anthony Serdyukov


People also ask

How to specify namespace in XPath expression?

Within RUEI, all namespaces used in your XPath queries must be explicitly defined. If a namespace is used in a query, but is not defined, it will not work. To define a namespace, do the following: Select Configuration, then General, Advanced settings, and then XPath namespaces.

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".

What is local name () in XPath?

The local-name function returns a string representing the local name of the first node in a given node-set.


3 Answers

If the same prefix can be bound to different namespaces and prefixes aren't known in advance, then the only pure XPath way to specify such expressions is to use this form of referring to elements:

someName[namespace-uri() = 'exactNamespace']

So, a particular XPath expression would be:

/*/a[namespace-uri() = 'defaultNS']/b[namespace-uri() = 'NSB']
                                         /c[namespace-uri() = 'defaultNS']
like image 167
Dimitre Novatchev Avatar answered Oct 19 '22 13:10

Dimitre Novatchev


I don't know any way to define a namespace prefix in an XPath expression.

But you can write the XPath expression to be agnostic of namespace-prefixes by using local-name() and namespace-uri() functions where appropriate.

Or if you know the XML-namespaces in advance, you can register an arbitrary prefix for them in the XmlNamespaceManager and tell your user to use that prefix in the XPath expression. It doesn't matter if the XML document itself registers a different prefix or no prefix at all. Path resolution is based on the namespace alone, not on the prefix.

Another option would be to scan the document at runtime (use XmlReader for low resource overhead if you haven't loaded it already) and then add the used mappings in the document in the XmlNamespaceManager. I'm not sure if you can get the namespaces and prefixes from XmlDocument, but I see no direct method to do it. It's easy with XmlReader though, since it exposes NamespaceURI and Prefix members for each node.

like image 29
TToni Avatar answered Oct 19 '22 14:10

TToni


Is there any possibility to specify namespaces declaration within xpath expression?

The answer is no - it's always done in the calling environment (which is actually more flexible).

An alternative would be to use XQuery, which does allow declaring namespaces in the query prolog.

UPDATE (2020)

In XPath 3.1 you can use the syntax /*/Q{http://my-namespace}a.

Sadly, though, if you're still using Microsoft software, then the situation hasn't changed since 2011 - you're still stuck with XPath 1.0 with all its shortcomings.

like image 2
Michael Kay Avatar answered Oct 19 '22 13:10

Michael Kay