Trouble with XPCOM XPathEvaluator
I'm having trouble evaluating XPaths using the nsIDOMXPathEvaluator from Mozillas XPCOM. I'm running the following javascript code through XPCShell:
[...]
var myPaths = new Array();
myPaths[0] = "/";
myPaths[1] = "/node()";
myPaths[2] = "/html";
for(i in myPaths) {
myPath = myPaths[i];
var document = doms[0];
var xpEval = Components.classes["@mozilla.org/dom/xpath-evaluator;1"].createInstance(Components.interfaces.nsIDOMXPathEvaluator);
var ns = xpEval.createNSResolver(document.documentElement);
var type = Components.interfaces.nsIDOMXPathResult.UNORDERED_NODE_SNAPSHOT_TYPE;
var res = xpEval.evaluate(myPath, document.documentElement, ns, type, null);
dump("\nPath: "+myPath+"\n");
dump("Result length: "+res.snapshotLength+"\n");
for ( var i=0 ; i < res.snapshotLength; i++ )
dump("... Node: "+res.snapshotItem(i)+"\n");
dump("... ... .nodeName: "+res.snapshotItem(i).nodeName+"\n");
}
[...]
The doms-list is an array of html-documents parsed using do_parse_document from the xpcshell testing utilities. The top of all documents are:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
My trouble is that the XPaths I use as input doesn't quite return what I expect. Below is the output from the above snippet:
Path: /
Result length: 1
... Node: [object XMLDocument]
... ... .nodeName: #document
Path: /node()
Result length: 2
开发者_JAVA技巧... Node: [object DocumentType]
... ... .nodeName: html
... Node: [object HTMLHtmlElement]
... ... .nodeName: html
Path: /html
Result length: 0
Path: //html
Result length: 0
I would expect at least 1 or 2 results from the /html and //html paths. (Those returned when using /node() as path)
I can't get correct output when doing queries like count(//p) either (that one returns 0 although there are plenty of paragraphs in the document).
I have tried calling document.evaluate() instead of xpEval.evaluate() with the same results. I have tried just passing null for namespace, same results.
Am I making some stupid mistake(s), or might there be some quirks in the nsIDOMXPathEvaluator that means I can't use it how I intend?
Thanks for your time!
Regards, Torin
Dump the namespaceURI property of the document.documentElement node, it is likely in the XHTML namespace http://www.w3.org/1999/xhtml and in that case with XPath 1.0 to select elements in any namespace you need to bind a prefix to the namespace URI and use that prefix. With the API you use you have to make sure your namespace resolver resolves your choosen prefix to the XHTML namespace URI. So you need e.g.
var nsResolver = function (prefix) { if (prefix === 'xhtml') return 'http://www.w3.org/1999/xhtml'; else return null; };
var res = xpEval.evaluate(myPath, document, nsResolver, type, null);
and then paths like /xhtml:html
or /xhtml:html/xhtml:body/xhtml:h1
.
精彩评论