Select namespaced elements in XPath without specifying the namespace.
Every once in a while you need to get to an XML element that is tucked within some namespace or another, but you really are not in the mood to deal with namespaces. You really don’t want to mess with XmlNamespaceManager or its ilk; or maybe you only have XPath to work with.
When this comes up, it usually takes me a few moments to remember, but the magic is the local-name() function.
XML
<gw:bookstore xmlns:gw="http://www.moonbats.com/gw"> <gw:book> <gw:title>Warming Up To The New Ice Age</gw:title> <gw:author>A. Nother Lemming</gw:author> </gw:book> <gw:book> <gw:title>The Sky Is Falling</gw:title> <gw:author>Chicken Little</gw:author> </gw:book> <gw:book> <gw:title>Glaciers Will Burn Us All</gw:title> <gw:author>Chicken Little</gw:author> </gw:book> <gw:book> <gw:title>Data: A Cookbook</gw:title> <gw:author>Grant Me Money</gw:author> </gw:book> </gw:bookstore>
XPath
//*[local-name()='title']
This basically says to select any element where the local name, i.e. the element name minus the namespace, is equal to ‘title’.
This can be extended with other XPath functions. In the following example we want to get the titles of books by Chicken Little.
//*[ local-name() = 'title' and (../*[local-name() = 'author' and contains( text(), 'Chicken Little' ) ]) ]
Here we’re selecting elements with a local name of ‘title’ and a sibling element named author and where that sibling’s value contains ‘Chicken Little’.
This syntax is not as convenient as something like /*:title, but at least it does the trick.

0 responses so far ↓
There are no comments yet...Kick things off by filling out the form below.
Leave a Comment