I have some JavaScript/Xpath which isn't working as I would expect. (available on jsfiddle) It would seem that I'm doing something wrong with an XML namespace, preventing me from querying for my elements by their node (tag) names.
If I try querying for all child nodes of the current node, I find the element myElement
without problem:
var xpathResult = xmlDoc.evaluate( "child::*", rootElement, nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var queryEl;
if(queryEl = xpathResult.iterateNext()) {
alert("child::* found element " + queryEl.nodeName);
}
else {
alert("child::* found nothing!");
}
... but if I specifically target the nodes with myElement
node (tag) names I get no results:
/* Now try getting only those children with nodeName `myElement` */
xpathResult = xmlDoc.evaluate( "child::myElement", rootElement, nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var queryEl;
if(queryEl = xpathResult.iterateNext()) {
alert("child::myElement found element " + queryEl.nodeName);
}
else {
alert("child::myElement found nothing!");
}
What am I doing wrong?
I have some JavaScript/Xpath which isn't working as I would expect. (available on jsfiddle) It would seem that I'm doing something wrong with an XML namespace, preventing me from querying for my elements by their node (tag) names.
If I try querying for all child nodes of the current node, I find the element myElement
without problem:
var xpathResult = xmlDoc.evaluate( "child::*", rootElement, nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var queryEl;
if(queryEl = xpathResult.iterateNext()) {
alert("child::* found element " + queryEl.nodeName);
}
else {
alert("child::* found nothing!");
}
... but if I specifically target the nodes with myElement
node (tag) names I get no results:
/* Now try getting only those children with nodeName `myElement` */
xpathResult = xmlDoc.evaluate( "child::myElement", rootElement, nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var queryEl;
if(queryEl = xpathResult.iterateNext()) {
alert("child::myElement found element " + queryEl.nodeName);
}
else {
alert("child::myElement found nothing!");
}
What am I doing wrong?
Share Improve this question edited Mar 8, 2012 at 17:12 Richard JP Le Guen asked Mar 8, 2012 at 17:02 Richard JP Le GuenRichard JP Le Guen 28.7k8 gold badges93 silver badges120 bronze badges 2- Can you please split you problem to show just the problem? As a short and (in)valid example? – powtac Commented Mar 8, 2012 at 17:07
- @powtac - Tried... but the code really only creates an XML doc and then makes 2 queries against it. It really is just a test case. – Richard JP Le Guen Commented Mar 8, 2012 at 17:14
1 Answer
Reset to default 8Try this as your resolver:
var nsResolver = (function (element) {
var
nsResolver = element.ownerDocument.createNSResolver(element),
defaultNamespace = element.getAttribute('xmlns');
return function (prefix) {
return nsResolver.lookupNamespaceURI(prefix) || defaultNamespace;
};
} (xmlDoc.documentElement));
You will also have to select the elements like this:
"child::default:myElement"
// where 'default' can be anything, as long as there is a namespace
Further reading:
- https://developer.mozilla/en/DOM/document.createNSResolver
- https://developer.mozilla/en/Introduction_to_using_XPath_in_JavaScript (=> Implementing a Default Namespace Resolver)
- http://www.w3/TR/DOM-Level-3-XPath/xpath.html#XPathNSResolver-lookupNamespaceURI
Your fiddle: http://jsfiddle/chKZc/5/ (updated)