I'm creating a Firefox for Android extension and I have a problem with a XML document retrieved from a XMLHttpRequest
: I can't find a way to select a node. The better solution I found is this, but I got this error when selecting with xpath on the document:
WrongDocumentError: Node cannot be used in a document other than the one in which it was created
This is my code:
var parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
var parsedXml = parser.parseFromString(xmlhttp.responseText, "text/xml");
var xpathExpression = "//td[contains(.,'Raw text')]/../td[2]/pre";
var res = window.content.document.evaluate(xpathExpression, parsedXml, null, window.XPathResult.STRING_TYPE , null);
If I replace the "evaluate" with the next line:
var res = parsedXml.selectSingleNode(xpathExpression);
Then I get the following error:
[JavaScript Error: "parsedXml.selectSingleNode is not a function" {file: "resource://gre/modules/addons/XPIProvider.jsm -> jar:file:///data/data/org.mozilla.fennec/files/mozilla/ggz9zzjr.default/extensions/qrReader@qrReader.xpi!/bootstrap.js" line: 61}]
Well, the name of the exception, WrongDocumentErrort
gave it away. You're trying to call .evaluate()
on a DOM (Document
) that does not belong to the same Document .evaluate()
is bound to.
The nsIDOMParser
will actually return a new XMLDocument
that has an .evaluate()
itself, which you'll have to use.
var parser = Cc["@mozilla.org/xmlextras/domparser;1"].
createInstance(Ci.nsIDOMParser);
var parsedDoc = parser.parseFromString(
'<?xml version="1.0"?>\n<doc><elem>Raw text</elem></doc>',
"text/xml");
var xpathExpression = "//elem[contains(.,'Raw text')]";
var res = parsedDoc.evaluate(
xpathExpression,
parsedDoc,
null,
XPathResult.STRING_TYPE,
null);
console.log(res, res.stringValue);
Instead using nsIDOMParser
, since your content seems to be originating from XHR
anyway, and seems to be (X)HTML (indicated by your expression), it might be better to use XHR.responseType = "document"
instead, which will parse a DOM from the response using the HTML parser.
var req = new XMLHttpRequest();
req.onload = function() {
var doc = req.response;
var h1 = doc.evaluate("//h1", doc, null, XPathResult.STRING_TYPE, null);
console.log(h1.stringValue);
// Alternative in some cases
h1 = doc.querySelector("h1");
console.log(h1.textContent);
};
req.open("GET", "http://example.org/");
req.responseType = "document"; // Parse as text/html
req.send();