chama
chama

Reputation: 6163

My xpath query isn't finding any results

I have a simple xml node, and an equally simple xpath query expression, but it's not working properly. I've tried all sorts of variations on it (//node-name, *[name()='node-name'], current-node-name/node-name), but it's still not finding the correct node!

Here's my xml:

<page-reference xmlns="http://something.com">
  <relative-path>something/something</relative-path>
  <base-path>somePath</base-path>
</page-reference>

I've tried a few different variations of x-paths. Most of them work if I take out the xmlns attribute of the page-reference tag. For example: //relative-path, /page-reference/relative-path, relative-path, page-reference/relative-path, but none of them work with the xmlns attribute.

Any ideas what could be causing this? I thought that it's the double slash after the http in the value, but I have no idea why that would cause an issue, and it also does not seem to be the case.

Upvotes: 3

Views: 728

Answers (3)

Brett Zamir
Brett Zamir

Reputation: 14355

The xmlns attribute provides a namespace for the element, meaning it is not just a normal "page-reference" or "relative-path" element, so it cannot be accessed as such. Different languages have different ways of indicating the namespace, from indicating the default for your XPath queries to using prefixes.

For JavaScript, you can use a namespace resolver: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#Implementing_a_User_Defined_Namespace_Resolver (if you want to specify prefixes--useful when there are different namespaces used within the document) and/or to rely on a default namespace within XPath expressions (though you need to use some--ANY--prefix): https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#Implementing_a_default_namespace_for_XML_documents

var xml = new DOMParser().parseFromString('<page-reference xmlns="http://something.com">'+
  '<relative-path>something/something</relative-path>'+
  '<base-path>somePath</base-path>'+
'</page-reference>', 'text/xml');

function resolver() {
    return 'http://something.com';
}
var refs = xml.evaluate('//x:page-reference', xml, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
alert(refs.snapshotItem(0).nodeName) // 'page-reference'

You'll need a shim for IE support. (A quick search turned up http://sourceforge.net/projects/js-xpath/files/js-xpath/ )

Upvotes: 2

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243569

Or, alternatively, you could use:

//*[name()='relative-path']

Upvotes: 2

hall.stephenk
hall.stephenk

Reputation: 1165

XPath is not aware of a "default" XML namespace (xmlns). As a result, you'll need to prefix all of your nodes in your XPath expressions with the page-reference tag's namespace.

XML:

<page-reference xmlns:s="http://something.com">
  <relative-path>something/something</relative-path>
  <base-path>somePath</base-path>
</page-reference>

XPath:

//s:relative-path

Upvotes: 1

Related Questions