Xml Firefox XPCOM插件:“您可以使用;意外错误“;用于xslt转换

Xml Firefox XPCOM插件:“您可以使用;意外错误“;用于xslt转换,xml,firefox,xslt,firefox-addon,xpcom,Xml,Firefox,Xslt,Firefox Addon,Xpcom,我正在尝试更新/重构一个遗留的Firefox扩展,该扩展广泛使用XPCOM API。我们为一个专门的应用程序进行了大量XSLT转换和客户端文件IO 不过,在处理XSLT转换时,我不断遇到奇怪的错误 transformiix start name of first node in the file file:///Users/sabrina/Documents/tmp/foo.xml: foo name of first node in the file file:///Users/sabrina

我正在尝试更新/重构一个遗留的Firefox扩展,该扩展广泛使用XPCOM API。我们为一个专门的应用程序进行了大量XSLT转换和客户端文件IO

不过,在处理XSLT转换时,我不断遇到奇怪的错误

transformiix start
name of first node in the file file:///Users/sabrina/Documents/tmp/foo.xml: foo
name of first node in the file file:///Users/sabrina/Documents/xslt/foostyle.xslt: xsl:stylesheet
transformiix error: [Exception... "Unexpected error"  nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)"  location: "JS frame :: chrome://xulschoolhello/content/test.js :: ProcTest.Test.makeAndShow :: line 30"  data: no]
“意外错误”到底是什么?是什么原因造成的?在我得到更令人困惑的“NS_ERROR_FAILURE(0x80004005)”之前,这相当于Firefox举手耸耸肩

欢迎提出任何意见或建议!提前感谢。:)

编辑添加:我之前应该说,因为这可能会影响答案:我在Firefox38 ESR的MacOSX上运行这个。接下来我将尝试调用外部xsltproc进程,不过我更喜欢使用Firefox的本机处理器。我想知道这是否是某种文件权限问题?请让我知道你的想法

我已经修改了Helloworld2扩展以包含以下代码:

ProcTest.Test = {
    base: "file:///Users/sabrina/Documents/",
    consoleService: Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService),

    makeAndShow: function() {
        var outXML = null;

        ProcTest.Test.consoleService.logStringMessage("transformiix start");
        try {
            // load xml
            var xmlDoc = ProcTest.Test.readXML(ProcTest.Test.base + "tmp/foo.xml");
        } catch (x) {
            ProcTest.Test.consoleService.logStringMessage("error loading xml: " + x);
            return false;
        }

        try {
            // get xslt processor
            var xsltProc = ProcTest.Test.getXSLTProc(ProcTest.Test.base + "xslt/foostyle.xslt");
        } catch (x) {
            ProcTest.Test.consoleService.logStringMessage("error getting processor: " + x);
            return false;
        }

        // send in the params
        xsltProc.setParameter(null, "blah", "thingy!")

        try {
            // transform!
            outXML = xsltProc.transformToDocument(xmlDoc);
        } catch (x) {
            ProcTest.Test.consoleService.logStringMessage("transformiix error: " + x);
            return false;
        }

        try {
            // save
            ProcTest.Test.saveXML(outXML, ProcTest.Test.base + "xhtml/login.xhtml");
        } catch (x) {
            ProcTest.Test.consoleService.logStringMessage("error saving xml: " + x);
            return false;
        }
        ProcTest.Test.consoleService.logStringMessage("looks like it worked!")
        content.window.location.replace(ProcTest.Test.base + "xhtml/login.xhtml")
    },

    readXML: function(filepath) {
        var myXMLHTTPRequest = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Components.interfaces.nsIXMLHttpRequest);
        myXMLHTTPRequest.open("GET", filepath, false);
        myXMLHTTPRequest.send(null);

        ProcTest.Test.consoleService.logStringMessage("name of first node in the file " + filepath + ": " + myXMLHTTPRequest.responseXML.firstChild.nodeName)
        return myXMLHTTPRequest.responseXML;
    },

    getXSLTProc: function(xslt) {
        var xslStylesheet = ProcTest.Test.readXML(xslt);

        var xsltProcessor = Components.classes["@mozilla.org/document-transformer;1?type=xslt"].createInstance(Components.interfaces.nsIXSLTProcessor)
        xsltProcessor.importStylesheet(xslStylesheet);

        return xsltProcessor
    },

    saveXML: function (doc, path) {
        try {
            var serializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(Components.interfaces.nsIDOMSerializer);

            // get or create a file object
            var file = ProcTest.Test.fileObject(path)

            // prepare the xml object
            var xml = doc
            xml = content.document.implementation.createDocument('', '', doc.doctype)
            xml.appendChild(xml.importNode(doc.documentElement, true))

            // prepare the output stream object
            var output = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream)
            output.init(file, 0x20 | 0x02 | 0x08, 0665, 0)

            // send the file to the output stream
            serializer.serializeToStream(xml, output, 'UTF-8')
            output.flush()
            output.close()
        } catch(e) {
            ProcTest.Test.consoleService.logStringMessage("error saving xml: " + e)
        }
    },

    fileObject: function(path) {
        var file = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile)

        try {
            file.initWithPath(ProcTest.Test.base)
            var splitPath = path.split('/')
            for (var i = 0; i < splitPath.length; ++i) {
                file.appendRelativePath(splitPath[i])
                if (i < splitPath.length - 1) {
                    if (file.exists()) {
                        if (!file.isDirectory)
                            throw "expecting directory: " + file.path
                        } else {
                            file.create(Components.interfaces.nsILocalFile.DIRECTORY_TYPE, 0775)
                        }
                }
            }
        } catch (e) {
            ProcTest.Test.consoleService.logStringMessage("error making file " + path + ": " + e)
            throw e
        }
        return file
    },
}
ProcTest.Test={
基数:“file:///Users/sabrina/Documents/",
consoleService:Components.classes[“@mozilla.org/consoleService;1”].getService(Components.interfaces.nsicsoleService),
makeAndShow:function(){
var-outXML=null;
ProcTest.Test.consoleService.logStringMessage(“transformiix启动”);
试一试{
//加载xml
var xmlDoc=ProcTest.Test.readXML(ProcTest.Test.base+“tmp/foo.xml”);
}捕获(x){
logStringMessage(“加载xml时出错:+x”);
返回false;
}
试一试{
//获取xslt处理器
var xsltProc=ProcTest.Test.getXSLTProc(ProcTest.Test.base+“xslt/foostyle.xslt”);
}捕获(x){
ProcTest.Test.consoleService.logStringMessage(“获取处理器时出错:+x”);
返回false;
}
//发送参数
setParameter(null,“blah”,“thingy!”)
试一试{
//转变!
outXML=xsltProc.transformToDocument(xmlDoc);
}捕获(x){
ProcTest.Test.consoleService.logStringMessage(“transformiix错误:+x”);
返回false;
}
试一试{
//拯救
ProcTest.Test.saveXML(outXML,ProcTest.Test.base+“xhtml/login.xhtml”);
}捕获(x){
logStringMessage(“保存xml时出错:+x”);
返回false;
}
ProcTest.Test.consoleService.logStringMessage(“看起来它工作了!”)
content.window.location.replace(ProcTest.Test.base+“xhtml/login.xhtml”)
},
readXML:函数(文件路径){
var myXMLHTTPRequest=Components.classes[“@mozilla.org/xmlextas/xmlhttprequest;1”].createInstance(Components.interfaces.nsIXMLHttpRequest);
myXMLHTTPRequest.open(“GET”,filepath,false);
myXMLHTTPRequest.send(null);
ProcTest.Test.consoleService.logStringMessage(“文件“+filepath+”:“+myXMLHTTPRequest.responseXML.firstChild.nodeName中第一个节点的名称”)
返回myXMLHTTPRequest.responseXML;
},
getXSLTProc:function(xslt){
var xsltylesheet=ProcTest.Test.readXML(xslt);
var xsltProcessor=Components.classes[“@mozilla.org/document transformer;1?type=xslt”].createInstance(Components.interfaces.nsIXSLTProcessor)
导入样式表(xslStylesheet);
返回xsltProcessor
},
saveXML:函数(文档、路径){
试一试{
var serializer=Components.classes[“@mozilla.org/xmlextras/xmlserializer;1”].createInstance(Components.interfaces.nsIDOMSerializer);
//获取或创建文件对象
var file=ProcTest.Test.fileObject(路径)
//准备xml对象
var xml=doc
xml=content.document.implementation.createDocument(“”,,,doc.doctype)
appendChild(xml.importNode(doc.documentElement,true))
//准备输出流对象
var output=Components.classes['@mozilla.org/network/file output stream;1'].createInstance(Components.interfaces.nsIFileOutputStream)
init(文件,0x20 | 0x02 | 0x080665,0)
//将文件发送到输出流
serializer.serializeToStream(xml,输出'UTF-8')
output.flush()
output.close()
}捕获(e){
logStringMessage(“保存xml时出错:+e”)
}
},
fileObject:函数(路径){
var file=Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile)
试一试{
file.initWithPath(ProcTest.Test.base)
var splitPath=path.split(“/”)
对于(变量i=0;i
以下是我的原始文件: foo.xml


苹果
橘子
foostyle.xslt

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output encoding="UTF-8" method="xml" indent="yes"/>

    <xsl:param name="blah"/>

    <xsl:template match="bar">
        <option value="text()">
            <xsl:value-of select="text()"/>
        </option>
    </xsl:template>

    <xsl:template match="foo">
        <select id="bars">
            <xsl:apply-templates select="bar"/>
        </select>
    </xsl:template>


    <xsl:template match="/">
        <html>
            <head>
                <title>Foo</title>
            </head>

            <body>
                <div id="foo">
                    <xsl:apply-templates select="foo"/>
                </div>
                <div>blah: <xsl:value-of select="$blah"/></div>

            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

福
废话:
编辑。请参阅下面我的答案,在这里我使用外部进程解决了问题
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output encoding="UTF-8" method="xml" indent="yes"/>

    <xsl:param name="blah"/>

    <xsl:template match="bar">
        <option value="text()">
            <xsl:value-of select="text()"/>
        </option>
    </xsl:template>

    <xsl:template match="foo">
        <select id="bars">
            <xsl:apply-templates select="bar"/>
        </select>
    </xsl:template>


    <xsl:template match="/">
        <html>
            <head>
                <title>Foo</title>
            </head>

            <body>
                <div id="foo">
                    <xsl:apply-templates select="foo"/>
                </div>
                <div>blah: <xsl:value-of select="$blah"/></div>

            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>
transformiix start
xsltproc exit status code: 0
looks like it worked!
ProcTest.Test = {
    base: "file:///Users/sabrina/Documents/",
    consoleService: Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService),

    makeAndShow: function() {
        var xmlPath = ProcTest.Test.base + "tmp/foo.xml"
        var xsltPath = ProcTest.Test.base + "xslt/foostyle.xslt"
        var outPath = ProcTest.Test.base + "xhtml/foo.xhtml"

        var xsltProc = ProcTest.Test.base + "osx/bin/xsltproc"
        var pid = {}

        var FileUtils = Cu.import("resource://gre/modules/FileUtils.jsm").FileUtils

        ProcTest.Test.consoleService.logStringMessage("transformiix start");

        var args = []
        var proc = Components.classes['@mozilla.org/process/util;1'].createInstance(Components.interfaces.nsIProcess)

        // initialize the external proc call
        try {
            var file = new FileUtils.File( "/Users/sabrina/Documents/osx/bin/xsltproc" )
            proc.init(file)
        } catch (x) {
            ProcTest.Test.consoleService.logStringMessage("error initializing file object for proc: " + x);
            return false;
        }

        // set up the commandline args
        args.push('--output', outPath)
        args.push('--stringparam', 'blah', "thingy!")
        args.push(xsltPath, xmlPath)

        try {
            // transform!
            proc.run(true, args, args.length, pid);
        } catch (x) {
            ProcTest.Test.consoleService.logStringMessage("transformiix error: " + x);
            return false;
        }

        ProcTest.Test.consoleService.logStringMessage("xsltproc exit status code: " + proc.exitValue)
        if (proc.exitValue == 0) {
            ProcTest.Test.consoleService.logStringMessage("looks like it worked!")
            content.window.location.replace(outPath)
        } else {
            ProcTest.Test.consoleService.logStringMessage("xsltproc exit status code: " + proc.exitValue)
        }
    },

}