欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-28 16:42:53
由于前面的方法xslt需要在xml文件内部直接导入,而项目中用到的xml文件是系统生成的,只能提供路径,而没有办法改写xml里面的内容,所以需要找一个方法能够在外部将xml...
由于前面的方法xslt需要在xml文件内部直接导入,而项目中用到的xml文件是系统生成的,只能提供路径,而没有办法改写xml里面的内容,所以需要找一个方法能够在外部将xml和xslt关联在一起,这样既达到了目的,也可以应用于多个xml文件,方便管理。
先上代码,系统中使用module这个js进行打包,module这个工具是专门用来将js进行打包,这个工具以后的文章再做介绍,我自己现在只会使用,还没研究其底层的代码;这边我们将js写在一个文件里面,包括类以及类实现的方法,
下面是js代码:transform.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 += "<br>错误代码: ";
txt += serror.errorcode;
txt += "<br>错误原因: ";
txt += serror.reason;
txt += "<br>错误行号: ";
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
复制代码 代码如下:

<!doctype html public "-//w3c//dtd html 4.01 transitional//en">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type='text/javascript' src="transform.js"></script>
</head>
<body>
<script type="text/javascript">
var xml = "这里输入xml路径";
var xsl = "这里输入xsl路径";
var tempobj = new transformbinder(xml,xsl);
tempobj.registeraction(transformxslt);
tempobj.bind();
</script>
</body>
</html>

分析一下transform.js:
xmldom这个构造函数是用来创建xml的dom元素,对于ie和ff,创建dom的方法不一样,ie是用window.activexobject这个方法来创建,而ff用document.implementation.createdocument这个方法来创建,我们用这两个属性来判断是ie还是ff。
ie下针对不同版本的xml["msxml2.domdocument.5.0", "msxml2.domdocument.4.0", "msxml2.domdocument.3.0", "msxml2.domdocument","microsoft.xmldom"],用for循环进行遍历查找到对应的版本再new activexobject(arrsignatures[i])建立dom;
ff下用document.implementation.createdocument("", "", null);直接创建dom ;
如果浏览器不支持 xml dom object则throw错误 。
transformxslt这个构造函数用xslt将xml转换成html,ff下没有transformnode这个方法,所以我们自己构造了一个方法,
复制代码 代码如下:

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;
}

然后用这个方法实现转换,在处理错误上ie和ff又有不同的处理方法,ie比较简单,有一个parseerror属性装载错误信息,errorcode是错误的代码,reason是错误原因,line是错误的行号,还有其他一些信息,这里只要显示主要的错误信息就可以了,如果出错了就显示出错内容,如果没有出错则显示转换的结果sresult。ff下就比较复杂一点,用xmlserializer和xmlserializer.serializetostring()将xmldom转换为字符串,再将字符串转换成dom对象,在转换的过程中如果报错,就能得到包含有parsererror的信息,判断得到的字符串的tagname是不是parsererror,如果是则将dom对象再转换成字符串抛出字符串中的内容,如果不是则显示转换的结果sresult。
这里有几个注意点:
a.ie能检验出xml的dtd错误,而ff下只能检验出xml本身的语法错误;
b.因为需要在浏览器下判断错误,最终的结果不好合并,可能代码结构上看起来不太合理,这也是无奈之举。
用transformbinder这个类进行封装,便于扩展和修改。transformbinder.prototype.registeraction这个原型用于注册事件,再用transformbinder.prototype.bind将事件进行绑定,需要使用这个类的时候,只需要new transformbinder(xml,xsl),注册transformxslt事件,再bind进行绑定,这样就实现这个效果了。如果需要扩展,再创建新的构造函数,注册并绑定到这个类上就可以实现效果。
相关标签: xslt xml xhtml