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