22

I could not get the following xpath expression to work when the xml path namespace prefix set.

/bk:BookStore/bk:Books/bk:Book[text()='Time Machine']

XML is:

<BookStore xmlns:bk="http://www.bookstore.com/book#">
  <bk:Books>
    <bk:Book id="1">Time Machine></bk:Book>
  </bk:Books>
</bk:BookStore>
2
  • Post the code that executes the XPath query. Commented Oct 14, 2010 at 9:34
  • 5
    You need to pass the prefix/namespace-URI binding to your XPath engine. Why? Because prefixes are not important for name test, but namespace URI are. So a:node could select b:node as long as a and b prefixes are binding to the same namespace URI. Commented Oct 14, 2010 at 12:46

2 Answers 2

42

Or even better (and more portable), without the unnecessary prefix:

/*/*[local-name()='Books'] ... and so on

The function local-name ignores any prefix, which, as correctly stated by commenters, can vary.

Sign up to request clarification or add additional context in comments.

2 Comments

Why did someone downvote this? I found this an excellent solution to avoid dealing with namespaces, which are just annoying and unnecessary 99% of the time.
If the namespaces are just a hurdle you have to get past, imposed on you externally -- as they often are -- then this is definitely the way to go.
21

Without more information about the host language (in which you attempt to evaluate XPath expressions) it is not possible to provide an useful recommendation.

Generally, one needs to "register" a namespace with a namespace manager and this also associates a prefix to the registered namespace. Then, using this NamespaceManager object as an argument to the XPath-evaluation method, one can specify as argument to this method an XPath expression that contains names prefixed by that particular prefix.

Workarounds:

/*/*[name()='bk:Books']/*[name()='bk:Book' and text()='Time Machine']

4 Comments

I am using xml signature in java. I wan to select the elements to be signed using xpath in the trasnforms section. How do I give the xpath expression when I have prefixes and namespaces in my xml document.
@Ashwin: This answer shows exactly how to do this (one of the possible ways), without registering namespaces. The second possible way is to register the namespace to prefix bindings in which element names referenced in the XPath expression are -- then the XPath expression can contain prefixes and be more readable. This second way requires to use for the namespace registering implementation-provided APIs and one needs to read the appropriate documentation.
More proper 'workaround' is something like: //*[fn:namespace-uri()="http://www.bookstore.com/book#" and local-name()='Book']. Actually, it is not even a workaround, just a verbose xpath. For brevity there are the prefixes and the environment that you use to execute xpath should provide you with a way of specifying them (the prefixes used in the xpath can be different from those used in the XML file).
@DavidL.This is a useful workaround. However, it hardcodes the namespace-uri and must always be modified, if the namespace itself is modified. Imagine having to maintain many such expressions. The advantage of using a specific namespace prefix is that in such cases only a single modification would be necessary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.