发布于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里的关键设计。
这个函数负责创建XML的DOM对象。IE和Firefox(以及后来的现代浏览器)创建DOM的方式完全不同,所以得用分支判断。IE用window.ActiveXObject,但不同版本的MSXML库名字不一样,比如"MSXML2.DOMDocument.5.0"、"MSXML2.DOMDocument.4.0"等等,为了避免版本兼容问题,用一个数组循环尝试,找到哪个能跑就用哪个。Firefox则直接调用document.implementation.createDocument。如果浏览器两者都不支持,那就直接抛异常,告诉用户环境不行。
这个函数要做的是用XSLT把XML转换成HTML。Firefox没有transformNode方法,所以得自己给它加上。具体做法是通过XSLTProcessor对象,先导入样式表,然后执行转换,最后用XMLSerializer把结果序列化成字符串。
处理错误时,IE和Firefox的套路也截然不同。IE比较简单,parseError对象里直接装着错误代码、原因、行号等信息,出错就展示这些,没出错直接输出结果。Firefox就绕一点——先用XMLSerializer把DOM对象转成字符串,再用DOMParser解析回DOM,如果解析过程中报错,生成的DOM根节点标签名会变成parsererror,这时候再把这个错误DOM序列化成字符串并弹窗提示。
这里有两个经验点值得注意:
为了便于维护和扩展,我用TransformBinder这个类把整个流程封装起来。registerAction方法用来注册具体的转换函数(比如这里的transformXSLT),bind方法负责执行绑定。真正使用时,只需要new TransformBinder(XML, XSL),然后注册一下转换函数,最后调用bind()就搞定了。如果以后想换成别的转换逻辑,只需要再写一个新的构造函数,注册并绑定就完事,非常灵活。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8