商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 一个用xslt样式将xml解析为xhtml的类TransformBinder(兼容FF和IE7.0)

一个用xslt样式将xml解析为xhtml的类TransformBinder(兼容FF和IE7.0)

  发布于2026-07-22 阅读(0)

扫一扫,手机访问

之前我们聊过一种方法,需要把XSLT直接写在XML文件内部。但现实项目里,XML文件往往是系统自动生成的,你压根没法去改它的内容。那怎么办?其实有个更灵活的思路——在外部把XML和XSLT关联起来。这样一来,既解决了问题,又能把一份XSLT模板复用到多个XML文件上,管理起来也方便多了。

废话不多说,直接上代码。先看Ja vaScript脚本,我把它放在一个叫transform.js的文件里,类和方法都写在一起。至于打包工具module,它是个专门用来打包JS的工具,这里先不展开,我自己也还在摸索它的底层,能用就行。

var XmlDom=function(){
    if (window.ActiveXObject) { // IE
        var arrSignatures = ["MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0",
            "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument",
            "Microsoft.XmlDom"];
        for (var i=0; i < arrSignatures.length; i++) {
            try {
                var oXmlDom = new ActiveXObject(arrSignatures[i]);
                return oXmlDom;
            } catch (oError) {
                //ignore
            }
        }
        throw new Error("你的系统没有安装 MSXML.");
    } else if(document.implementation.createDocument){ // Firefox
        var oXmlDom = document.implementation.createDocument("", "", null);
        return oXmlDom;
    } else{
        throw new Error("浏览器不支持 XML DOM object.");
    }
}
var transformXSLT=function(_XML,_XSL) {
    if (window.Node) {
        Node.prototype.transformNode = function(XslDom) {
            var oProcessor = new XSLTProcessor();
            oProcessor.importStylesheet(XslDom);
            var oResultDom = oProcessor.transformToDocument(myXmlDom);
            var oSerializer = new XMLSerializer();
            var sXml = oSerializer.serializeToString(oResultDom, "text/xml");
            return sXml;
        }
    }
    var myXmlDom = new XmlDom();
    myXmlDom.async=false;
    var myXslDom = new XmlDom();
    myXslDom.async=false;
    myXmlDom.load(_XML);
    myXslDom.load(_XSL);
    var sResult=myXmlDom.transformNode(myXslDom);
    if(window.ActiveXObject){
        if(myXmlDom.parseError.errorCode != 0){
            var sError=myXmlDom.parseError;
            var txt = "";
            txt += "
错误代码: "; txt += sError.errorCode; txt += "
错误原因: "; txt += sError.reason; txt += "
错误行号: "; txt += sError.line; document.write(txt); }else{ document.write(sResult); } } else if(document.implementation.createDocument){ var oSerializer = new XMLSerializer(); var sXmlDom = oSerializer.serializeToString(myXmlDom, "text/xml"); var oParser = new DOMParser(); var oXmlDom = oParser.parseFromString(sXmlDom,"text/xml"); if (oXmlDom.documentElement.tagName == "parsererror") { var oXmlSerializer = new XMLSerializer(); var sXmlError = oXmlSerializer.serializeToString(oXmlDom); alert(sXmlError); } else { document.write(sResult); } } } var TransformBinder = function(XML,XSL) { this.XML = XML; this.XSL = XSL; } TransformBinder.prototype.registerAction = function(handlers) { this.handlers = handlers; } TransformBinder.prototype.bind = function() { var _this = this; this.handlers(_this.XML,_this.XSL); }

对应的HTML页面也很简单,新建一个XSLTtransform.htm,把下面这段代码放进去就行:











下面逐段拆解一下transform.js里的关键设计。

XmlDom构造函数:统一创建DOM

这个函数负责创建XML的DOM对象。IE和Firefox(以及后来的现代浏览器)创建DOM的方式完全不同,所以得用分支判断。IE用window.ActiveXObject,但不同版本的MSXML库名字不一样,比如"MSXML2.DOMDocument.5.0"、"MSXML2.DOMDocument.4.0"等等,为了避免版本兼容问题,用一个数组循环尝试,找到哪个能跑就用哪个。Firefox则直接调用document.implementation.createDocument。如果浏览器两者都不支持,那就直接抛异常,告诉用户环境不行。

transformXSLT函数:核心转换逻辑

这个函数要做的是用XSLT把XML转换成HTML。Firefox没有transformNode方法,所以得自己给它加上。具体做法是通过XSLTProcessor对象,先导入样式表,然后执行转换,最后用XMLSerializer把结果序列化成字符串。

处理错误时,IE和Firefox的套路也截然不同。IE比较简单,parseError对象里直接装着错误代码、原因、行号等信息,出错就展示这些,没出错直接输出结果。Firefox就绕一点——先用XMLSerializer把DOM对象转成字符串,再用DOMParser解析回DOM,如果解析过程中报错,生成的DOM根节点标签名会变成parsererror,这时候再把这个错误DOM序列化成字符串并弹窗提示。

这里有两个经验点值得注意:

  • IE能校验出XML的DTD(文档类型定义)错误,但Firefox只能检查XML本身的语法错误。
  • 因为需要在浏览器环境下实时判断错误,导致代码结构看起来有点绕,但这也是没办法的事,毕竟浏览器之间的差异摆在那里。

TransformBinder类:封装与扩展

为了便于维护和扩展,我用TransformBinder这个类把整个流程封装起来。registerAction方法用来注册具体的转换函数(比如这里的transformXSLT),bind方法负责执行绑定。真正使用时,只需要new TransformBinder(XML, XSL),然后注册一下转换函数,最后调用bind()就搞定了。如果以后想换成别的转换逻辑,只需要再写一个新的构造函数,注册并绑定就完事,非常灵活。

本文转载于:https://www.jb51.net/article/21056.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注