一个用xslt样式将xml解析为xhtml的类TransformBinder(兼容FF和IE7.0)_
一个用xslt样式将xml解析为xhtml的类TransformBinder(兼容FF和IE7.0)_ 由于前面的方法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(arrSignaturesi); 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(arrSignaturesi)建立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进行绑定,这样就实现这个效果了。假如需要扩展,再创建新的构造函数,注册并绑定到这个类上就可以实现效果。 更多信息请查看IT技术专栏 .