我正在尝试关注this article来评估XPath表达式。我的代码是从文章中复制/粘贴的:
// Evaluate an XPath expression aExpression against a given DOM node
// or Document object (aNode), returning the results as an array
// thanks wanderingstan at morethanwarm dot mail dot com for the
// initial work.
function evaluateXPath(aNode, aExpr) {
var xpe = new XPathEvaluator();
var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
aNode.documentElement : aNode.ownerDocument.documentElement);
var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
var found = [];
var res;
while (res = result.iterateNext())
found.push(res);
return found;
}
但是,我收到此错误:
消息:ReferenceError:未定义XPathEvaluator
也许是Mozilla的文章过时了吗?是否有关于在SDK附加组件中解析XML的更新文章?
编辑。当我这样尝试时:
var {Cc, Ci} = require("chrome");
var domXPathEvaluator = Cc["@mozilla.org/dom/xpath-evaluator;1"].createInstance(Ci.nsIDOMXPathEvaluator);
我收到了一条很长的错误消息:
- message = Component returned failure code: 0x80570019 (NS_ERROR_XPC_CANT_CREATE_WN) [nsIJSCID.createInstance]
- fileName = undefined
- lineNumber = 14
- stack = @undefined:14:undefined|@resource://helloworld-addon/index.js:14:25|run@resource://gre/modules/commonjs/sdk/addon/runner.js:145:19|startup/</<@resource://gre/modules/commonjs/sdk/addon/runner.js:86:7|Handler.prototype.process@resource://gre/modules/Promise-backend.js:920:23|this.PromiseWalker.walkerLoop@resource://gre/modules/Promise-backend.js:799:7|this.PromiseWalker.scheduleWalkerLoop/<@resource://gre/modules/Promise-backend.js:738:39|Promise*this.PromiseWalker.scheduleWalkerLoop@resource://gre/modules/Promise-backend.js:738:7|this.PromiseWalker.schedulePromise@resource://gre/modules/Promise-backend.js:762:7|this.PromiseWalker.completePromise@resource://gre/modules/Promise-backend.js:705:7|handler@resource://gre/modules/commonjs/sdk/addon/window.js:56:3|
- toString = function () /* use strict */ toString
编辑2.在这里,我只是发布我的整个代码,因为它清楚的东西比我想象的要奇怪。我使用包含this one to display a popup的Mozilla教程创建了一个hello-world插件。我进一步对其进行了修改,以便将文本附加到文件中,并进一步修改,以进行解析和修改XML。因此,生成的附加组件应该在弹出窗口中输入文本并将其附加到XML文件中。
var data = require("sdk/self").data;
var text_entry = require("sdk/panel").Panel({
contentURL: data.url("text-entry.html"),
contentScriptFile: data.url("get-text.js")
});
const fooFile = "/Users/sabrina/Documents/addon/foo.xml";
var {Cc, Ci} = require("chrome");
var parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
//var domXPathEvaluator = Cc["@mozilla.org/dom/xpath-evaluator;1"].createInstance(Ci.nsIDOMXPathEvaluator);
var foo = parser.parseFromString(readTextFromFile(fooFile), "application/xml");
// Create a button
require("sdk/ui/button/action").ActionButton({
id: "show-panel",
label: "Show Panel",
icon: {
"16": "./icon-16.png",
"32": "./icon-32.png",
"64": "./icon-64.png"
},
onClick: handleClick
});
// Show the panel when the user clicks the button.
function handleClick(state) {
text_entry.show();
}
text_entry.on("show", function() {
text_entry.port.emit("show");
});
text_entry.port.on("text-entered", function (text) {
console.log(text);
// appendTextToFile(text, "/Users/sabrina/Documents/addon/output.txt");
appendFoo(text);
text_entry.hide();
});
function appendFoo(text) {
var newNode = foo.createElement("blah");
newNode.innerHTML = text;
var mainFoo = evaluateXPath(foo, '/foo')[0];
mainFoo.appendChild(newNode);
foo.save(fooFile);
}
function evaluateXPath(aNode, aExpr) {
var xpe = new XPathEvaluator();
var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
aNode.documentElement : aNode.ownerDocument.documentElement);
//var result = domXPathEvaluator.evaluate(aExpr, aNode, null,
// domXPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var found = [];
var res;
while (res = result.iterateNext())
found.push(res);
return found;
}
function readTextFromFile(filename) {
var fileIO = require("sdk/io/file");
var text = null;
if (fileIO.exists(filename)) {
var TextReader = fileIO.open(filename, "r");
if (!TextReader.closed) {
text = TextReader.read();
TextReader.close();
}
}
console.log(arguments.callee.name + ": have read " + text + " from " + filename);
return text;
}
function writeTextToFile(text, filename) {
var fileIO = require("sdk/io/file");
var TextWriter = fileIO.open(filename, "w");
if (!TextWriter.closed) {
TextWriter.write(text + "\n");
console.log(arguments.callee.name + ": have written " + text + " to " + filename);
TextWriter.close();
}
function appendTextToFile(text, filename) {
var textplus = readTextFromFile(filename) + text;
writeTextToFile(textplus, filename);
}
我使用jpm run
在命令行运行,打开Firefox Developer Edition。我点击插件按钮,弹出窗口出现,我输入文字,然后点击返回,我在控制台中看到了这个:
JPM undefined Starting jpm run on Sabrina's Helloworld Addon
Creating XPI
JPM undefined XPI created at /var/folders/gg/r_hp4hzs0gdfy70f__l18fmr0000gn/T/@helloworld-addon-0.0.1.xpi (46ms)
Created XPI at /var/folders/gg/r_hp4hzs0gdfy70f__l18fmr0000gn/T/@helloworld-addon-0.0.1.xpi
JPM undefined Creating a new profile
console.log: helloworld-addon: readTextFromFile: have read <?xml version="1.0" encoding="UTF-8"?>
<foo><blah>eek</blah><foo>
from /Users/sabrina/Documents/addon/foo.xml
console.log: helloworld-addon: ook
console.error: helloworld-addon:
JPM undefined Message: ReferenceError: XPathEvaluator is not defined
Stack:
evaluateXPath@resource://gre/modules/commonjs/toolkit/loader.js -> resource://helloworld-addon/index.js:63:9
appendFoo@resource://gre/modules/commonjs/toolkit/loader.js -> resource://helloworld-addon/index.js:57:19
@resource://gre/modules/commonjs/toolkit/loader.js -> resource://helloworld-addon/index.js:50:2
emitOnObject@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/event/core.js:112:9
emit@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/event/core.js:89:38
portEmit@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/content/sandbox.js:343:7
emitOnObject@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/event/core.js:112:9
emit@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/event/core.js:89:38
onContentEvent/<@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/content/sandbox.js:384:5
delay/<@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/lang/functional/concurrent.js:38:20
notify@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/timers.js:40:9
答案 0 :(得分:1)
在另一个问题中,Wladimir Palant(Adblock Plus的作者,可能是他对Firefox有很好的了解)说:
是的,窗口上下文中提供的很多全局类都不在SDK模块中,而是作为沙箱。
来源:https://stackoverflow.com/a/10522459/3512867
这可以解释为什么在SDK插件中没有定义XPathEvaluator
。
合乎逻辑的结论是使用Firefox的Components
对象来访问nsIDOMXPathEvaluator
接口。这会出现以下错误:
NS_ERROR_XPC_CANT_CREATE_WN
从mozillazine的论坛用户&#34; lithopsian&#34;:
来看待我们的这一点。这意味着它无法为非javascript界面创建包装器。
来源:http://forums.mozillazine.org/viewtopic.php?f=19&t=2854793
我无法判断该声明的可信度,虽然链接的错误报告似乎是相关的,但我无法证明它们实际上是:
除非那些对Firefox内部工作有更深入了解的人确认(或驱散)这些信息,否则我只能犹豫地断定nsIDOMXPathEvaluator
界面根本无法在SDK插件中工作。< / p>