热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

一个用xslt样式将xml解析为xhtml的类TransformBinder(

这几天一直在研究xslt转换xml为xhtml,前面文章有介绍使用xslt将xml解析成xhtml的文章由于前面的方法xslt需要在xml文件内部直接导入,而项目中用到的xml文件是系统生成的,只能提供路径

       这几天一直在研究xslt转换xml为xhtml,前面文章有介绍 使用xslt将xml解析成xhtml 的文章
由于前面的方法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 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这个构造函数是用来创建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进行绑定,这样就实现这个效果了。如果需要扩展,再创建新的构造函数,注册并绑定到这个类上就可以实现效果。
 


推荐阅读
  • Apache Shiro 身份验证绕过漏洞 (CVE202011989) 详细解析及防范措施
    本文详细解析了Apache Shiro 身份验证绕过漏洞 (CVE202011989) 的原理和影响,并提供了相应的防范措施。Apache Shiro 是一个强大且易用的Java安全框架,常用于执行身份验证、授权、密码和会话管理。在Apache Shiro 1.5.3之前的版本中,与Spring控制器一起使用时,存在特制请求可能导致身份验证绕过的漏洞。本文还介绍了该漏洞的具体细节,并给出了防范该漏洞的建议措施。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • 分享css中提升优先级属性!important的用法总结
    web前端|css教程css!importantweb前端-css教程本文分享css中提升优先级属性!important的用法总结微信门店展示源码,vscode如何管理站点,ubu ... [详细]
  • 本文介绍了网页播放视频的三种实现方式,分别是使用html5的video标签、使用flash来播放以及使用object标签。其中,推荐使用html5的video标签来简单播放视频,但有些老的浏览器不支持html5。另外,还可以使用flash来播放视频,需要使用object标签。 ... [详细]
  • CSS|网格-行-结束属性原文:https://www.gee ... [详细]
  • css元素可拖动,如何使用CSS禁止元素拖拽?
    一、用户行为三剑客以下3个CSS属性:user-select属性可以设置是否允许用户选择页面中的图文内容;user-modify属性可以设置是否允许输入 ... [详细]
  • 使用python输入PDF编号自动下载freepatentsonline.com的文档#!usrbinenvpython3#codingutf-8#Version:python3. ... [详细]
  • 本文是一位90后程序员分享的职业发展经验,从年薪3w到30w的薪资增长过程。文章回顾了自己的青春时光,包括与朋友一起玩DOTA的回忆,并附上了一段纪念DOTA青春的视频链接。作者还提到了一些与程序员相关的名词和团队,如Pis、蛛丝马迹、B神、LGD、EHOME等。通过分享自己的经验,作者希望能够给其他程序员提供一些职业发展的思路和启示。 ... [详细]
author-avatar
小怡的宝_594
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有