微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

类TransformBinder将xml解析为xhtml的实例方法

这几天一直在研究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 < 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进行绑定,这样就实现这个效果了。如果需要扩展,再创建新的构造函数注册并绑定到这个类上就可以实现效果

原文地址:https://www.jb51.cc/xml/1194111.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。