JavaScript XML 兼容处理,序列化和反序列化以及回调事件


浏览器中XML DOM的支持

IE中通过ActiveXObject实现了XML的支持,存在一下几个版本:
Microsoft.XmlDom,MSXML2.DOMDocument,MSXML2.DOMDocument.3.0,MSXML2.DOMDocument.4.0,MXXML2.DOMDocument.5.0

IE678使用ActiveXObject来实现XML支持,可以通过loadXML()来传入XML字符串;
在现代浏览器下通过document.implementation.createDocument来实现XML支持,
反序列化需要通过DOMParse对象以及parseFromString方法来完成。

对于载入文档完成后的事件触发,IE678使用的是onreadystatechange事件以及判断readyState属性来得知状态;
对于现代浏览器使用的是onload事件。

对于一个XML对象,IE678提供了xml属性序列化;
对于现代浏览器,需要(new XMLSerializer).serializeToString来序列化。

如上分析,想要实现兼容,
可以通过document.prototype.loadXML来实现现代浏览器的loadXML兼容;
可以通过ES5的Object.defineProperty来定义现代浏览器的readyState属性,在set为4的时候触发onreadystatechange事件;
可以通过ES5的Object.defineProperty来定义现代浏览器的xml属性,读取的时候通过XMLSerializer对象来序列化。

不考虑异常和错误,测试代码如下:

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5 <style rel="stylesheet" type="text/css">
  6 </style>
  7 <script type="text/javascript">
  8 function createXMLDOM() {
  9     if(!createXMLDOM.cache){
 10         // 现代浏览器分支.
 11         if(document.implementation && document.implementation.createDocument){
 12             createXMLDOM.cache=function(){
 13                 var xmldom=document.implementation.createDocument("","",null);
 14 
 15                 // 兼容onreadystatechange方法.
 16                 _fix_onreadystatechange.call(xmldom);
 17                 // 添加一个触发事件.
 18                 xmldom.addEventListener("load",function(){
 19                     // 设置readyState为4.被动触发onreadystatechange事件.
 20                     this.readyState=4;
 21                 },false);
 22                 return xmldom;
 23             };
 24             // 兼容loadXML方法.
 25             _fix_loadXML();
 26             // 兼容xml属性
 27             _fix_xml();
 28             return createXMLDOM.cache();
 29         }
 30         // IE678分支.
 31         else if(window.ActiveXObject){
 32             var vs=["MSXML2.DOMDocument.5.0","MSXML2.DOMDocument.4.0",
 33             "MSXML2.DOMDocument.3.0","MSXML2.DOMDocument",
 34             "Microsoft.XmlDom"];
 35             for(var i=0,j=vs.length;i<j;i++){
 36                 try{
 37                     var oxmldom=new ActiveXObject(vs[i]);
 38                     createXMLDOM.cache=new Function("x","return new ActiveXObject('"+vs[i]+"');");
 39 
 40                     return oxmldom;
 41                 }
 42                 catch(ex){}
 43             }
 44         }
 45         // 都不兼容.
 46         else{
 47             createXMLDOM.cache=new Function("return null;");
 48             return null;
 49         }
 50     }
 51     else{
 52         return createXMLDOM.cache();
 53     }
 54 }
 55 
 56 /* loadXML的兼容处理.现代浏览器. */
 57 function _fix_loadXML(){
 58     Document.prototype.loadXML=function(sxml){
 59         var oparse=new DOMParser();
 60         var oxmldom=oparse.parseFromString(sxml, "text/xml");
 61         while(this.firstChild){
 62             this.removeChild(this.firstChild);
 63         }
 64         for(var i=0,j=oxmldom.childNodes.length;i<j;i++){
 65             // 获取另一个文档的某个节点以及所有子节点.
 66             var onewnode=this.importNode(oxmldom.childNodes[i],true);
 67             // 添加到该文档中.
 68             this.appendChild(onewnode);
 69         }
 70         // 这里修正readyState属性.
 71         this.readyState=4;
 72     };
 73 }
 74 /* 处理onreadystatechange的兼容. */
 75 function _fix_onreadystatechange(){
 76     if(Object.defineProperty){
 77         Object.defineProperty(this,"readyState",{
 78             get:function(){
 79                 return this.__readyState__;
 80             },
 81             set:function(i){
 82                 this.__readyState__=i;
 83                 this.onreadystatechange();
 84             }
 85         });
 86     }
 87 }
 88 /* 现代浏览器需要通过DOMParser对象并通过parseFromString来转换XML文档为字符串 */
 89 function _fix_xml(){
 90     // ES5新特性.
 91     if(Object.defineProperty){
 92         Object.defineProperty(Node.prototype,"xml",{
 93             get:function(){
 94                 return (new XMLSerializer).serializeToString(this,"text/xml");
 95             }
 96         })
 97     }
 98     // 如下分支IE9开始不支持了.非W3C标准.
 99     //else if(Node.prototype.__defineGetter__){
100     //    Node.prototype.__defineGetter__("xml",function(){
101     //        return (new XMLSerializer).serializeToString(this,"text/xml");
102     //    });
103     //}
104 }
105 
106 /* 测试 */
107 window.onload=function(){
108     var xml1=createXMLDOM();
109     var xml2=createXMLDOM();
110     xml2.onreadystatechange=function(){
111         // 这里不能用this.因为在处理ActiveX对象可能出现问题.
112         if(xml2.readyState==4){
113             document.body.innerHTML+="load xml ok<br/>";
114         }
115     }
116     xml2.loadXML("<xml><blog>xf_z1988</blog></xml>");
117     var xml_str=xml2.xml.replace(/</g,"&lt;").replace(/>/g,"&gt;");
118     document.body.innerHTML+=xml_str;
119 };
120 </script>
121 </head>
122 <body></body>
123 </html>

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM