Reputation: 851
I'm having an issue getting XPath to return anything. I've only tried in Firefox, but I've used a bunch of different examples and none of them are working.
function populateFilters(productType) {
callAjax.request({
url: './Products.xml',
onSuccess: function(rootNode, fullText) {
var path = '//product';
// code for IE
if (window.ActiveXObject)
var nodes=rootNode.selectNodes(path);
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation && document.implementation.createDocument)
var nodes=rootNode.evaluate(path, rootNode, null, 0, null);
for (var i = 0; i < nodes.length; ++i) {
nodes[i].childNodes[0];
}
},
onError: function(errCode, responseStatus) {alert('An error has occured. Please contact the site\'s Webmaster.\n\n' + errCode + '\n' + responseStatus);}
});
}
The ajax call is working fine... I'm getting the XML document and am able to navigate the DOM without issue. The problem I'm having is when the code hits the rootNode.evaluate()
call, nothing is returned. No errors, and no data. Here's an example snippet of the XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<product>
<type>Snowboard</type>
<brand>DC</brand>
</product>
<product>
<type>Skateboard</type>
<brand>Banana</brand>
</product>
<product>
<type>Clothing</type>
<brand>BoardDokter</brand>
</product>
</root>
The only thing I can think of is that the var path = '//product';
is incorrect, but I've looked at many examples, and it really should work.
Anyone have any ideas? Firefox 4 on Windows XP, and on Windows 7.
Upvotes: 0
Views: 7885
Reputation: 19134
document.evaluate
returns an XPathResult
object whose useful methods depend on the arguments:
4
) and ordered (5
) iterators give you an object with iterateNext()
, which returns each node and then returns null
.6
) and ordered (7
) snapshots give you an object with snapshotLength
and snapshotItem(index)
.0
) will give you an unordered iterator if your XPath expression returns nodes.Since the fourth argument to evaluate is 0, it gave you an unordered iterator which you have to call iterateNext()
on. This is probably not the one you want (most people want a guaranteed order).
See the Mozilla documentation on document.evaluate
or the W3C reference on document.evaluate
for more details.
var xml = '<?xml version="1.0" encoding="ISO-8859-1"?>\n' +
'<root>\n' +
' <product>\n' +
' <type>Snowboard</type>\n' +
' <brand>DC</brand>\n' +
' </product>\n' +
' <product>\n' +
' <type>Skateboard</type>\n' +
' <brand>Banana</brand>\n' +
' </product>\n' +
' <product>\n' +
' <type>Clothing</type>\n' +
' <brand>BoardDokter</brand>\n' +
' </product>\n' +
'</root>';
var path = '//product';
var doc = (new DOMParser).parseFromString(xml, 'text/xml');
// choice 1: use iterator
var it = doc.evaluate(path, doc, null, 5, null);
var nodes1 = [];
var node;
while (node = it.iterateNext()) {nodes1.push(node);}
// choice 2: use snapshot
var snapshot = doc.evaluate(path, doc, null, 7, null);
var nodes2 = [];
for (var i = 0; i < snapshot.snapshotLength; i++) {
nodes2.push(snapshot.snapshotItem(i));
}
Handy tip: type $x
into your Javascript console within Chrome to see the source of their function to turn XPath into a Javascript array.
Upvotes: 3