Firefox插件中的XPathEvaluator

时间:2015-08-03 21:42:08

标签: javascript xml firefox xpath

我正在尝试关注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

1 个答案:

答案 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>