漂泊的云

          javascript之XML DOM對象

          javacript中對xml dom的支持,與其他任何特性一樣面臨著瀏覽器兼容問題。

          一 IE中的XML DOM
          1.微軟通過ActiveX的MSXML庫提供了支持,通過:
           var oXmlDom = new ActiveXObject("MSXML2.DOMDocument.5.0")
          得到一個XML DOM對象,這是在IE6中的,如果你的IE是更老版本的,可以使用下面的函數得到,如果你沒有安裝MSXML,將不能得到:

           function createXMLDOM() {
                  
                      
          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");           
                  }     

          當然,如果你使用prototype庫,可以使用Try.these函數。

          2.XML DOM對象可以通過load和loadXML方法載入xml文件或者字符串:
               oXmlDom.load("test.xml");
               oXmlDom.loadXML(
          "<root></root>");
          然后這個oXmlDom就可以使用所有的DOM對象方法,比如documentElement.tagName,參見:
           《javascript之DOM技術(一)》
           《javascript之dom技術(二)》

          3.XML DOM默認是通過異步載入xml文件的,可以通過設置async值來選擇是同步還是異步:
          oXmlDom.async=true;


          4.
          IE的XML DOM擁有一個readyState值用來表示載入文件的狀態:

          0——準備載入
          1——正在載入
          2——載入完成
          3——載入完成并可用,但有一部分數據也許不可用
          4——完全載入,完全可用。

          相應的有一個onreadystatechange事件,當狀態改變時發生,我們可以通過監聽此事件來判斷XML DOM對象的可用性
          oXmlDom.onreadystatechange = function () {
                          
          if (oXmlDom.readyState == 4) {
                              alert(
          "load test.xml done!");
                              alert(
          "Tag name of the root element is " + oXmlDom.documentElement.tagName);
                              alert(
          "The root element has this many children: " + oXmlDom.documentElement.childNodes.length);

                          }
                      };

          5.IE的XML DOM對象有一個xml屬性,用來返回xml文件的字符串形式,比如
          oXmlDom.async=false;
          oXmlDom.load(
          "test.xml");
          alert(oXmlDom.xml);

          alert出:<root><child/><child/></root>

          6.IE,當載入的XML文件或者字符串解析錯誤時,將產生一個parseError對象,我們在下面的代碼中演示此對象的屬性:
                      oXmlDom.async = false;
                      oXmlDom.load(
          "errors.xml");
                      
                      
          //0表示沒有錯誤
                      if (oXmlDom.parseError != 0) {
                          
          var oError = oXmlDom.parseError;
                      
                          alert(
          "An error occurred:\n錯誤代碼: "
                                
          + oError.errorCode + "\n"
                                
          + "行數: " + oError.line + "\n"
                                
          + "列數: " + oError.linepos + "\n"
                                
          + "原因: " + oError.reason);
                                
                      }


          二.Mozilla的XML DOM對象
          1.XML DOM對象的創建,符合DOM標準的,通過document.implementation.createDocument()方法。比如:
          var oXmlDom=document.implementation.createDocument("","",null);

          這三個參數分別是文檔命名空間、文檔元素的標簽名以及一個文檔類型對象(總為null),比如:
          var oXmlDom=document.implementation.createDocument("http://www.rubyeye.net","root",null);

          這段代碼創建了一個<a0:root xmlns="http://www.rubyeye.net"/>的XML DOM對象


          2.載入xml,Mozilla與IE不同的是只提供了一個load()方法用于載入xml文件,沒有提供loadXML()方法用于載入XML字符串。同步載入XML文件的代碼與IE相同:
          oXmlDom.async=false;
          oXmlDom.load(
          "test.xml");

          異步載入稍有不同,因為Mozilla并不支持readyState屬性,并且沒有onreadystatechange事件,它只有一個onload的事件,當載入完成時觸發;或者說相當于IE的readyState屬性等于4的狀態。
          oXmlDom.onload=function(){
          alert(
          "done");
          }
          oXmlDom.load(
          "test.xml");

          要將XML字符串解析為DOM對象,必須使用DOMParser對象:
          var oParser=new DOMParser();
          var oXmlDom=oParser.parseFromString(
          "<root><child/></root>,"text/xml");

          兩個參數:要解析的XML字符串以及字符串的內容類型(只能為text/xml或者application/xml)。
          不過我們可以實現自己的loadXML方法:
            Document.prototype.loadXML = function (sXml) {
              
                      
          var oParser = new DOMParser();
                      
          var oXmlDom = oParser.parseFromString(sXml, "text/xml");
                   
                      
          //刪除原文檔內容
                      while (this.firstChild) {
                          
          this.removeChild(this.firstChild);
                      }
                      
          //導入新的文檔內容
                      for (var i=0; i < oXmlDom.childNodes.length; i++) {
                          
          var oNewNode = this.importNode(oXmlDom.childNodes[i], true);
                          
          this.appendChild(oNewNode);
                      }
                  
                  };

          3.Mozilla沒有提供IE的xml屬性來返回XML文檔內容,只能通過使用XMLSerializer對象:
          var oSerializer=new XMLSerializer();
          var sXml=oSerializer.serializeToString(oXmlDom,"text/xml");
          同樣兩個參數:XML DOM對象以及轉化成的文檔類型。

          同樣,我們也可以給Mozilla的XML DOM對象定義一個屬性xml,通過defineGetter方法:
          Node.prototype.__defineGetter__("xml",function(){
          var oSerializer=new XMLSerializer();
          var sXml=oSerializer.serializeToString(this,"text/xml");
          });

          以后就可以以IE的方式,oXmlDom.xml來獲取XML文檔內容。

          4。錯誤處理,同樣與IE不同,Mozilla當解析錯誤時會返回一段代碼,以標簽<prasereoor>包括其中的代碼解釋了錯誤發生的原因以及位置等信息,我們只有通過正則表達式解析此段代碼,提取錯誤信息。
                var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
                     
                      
          //返回代碼的標簽名為parsererror,表示錯誤發生
                      if (oXmlDom.documentElement.tagName == "parsererror") {
                          reError.test(oXmlDom.xml);
                          alert(
          "An error occurred:\n描述: "
                              
          + RegExp.$1 + "\n"
                              
          + "文件名: " + RegExp.$2 + "\n"
                              
          + "行數: " + RegExp.$3 + "\n"
                              
          + "列數: " + RegExp.$4 + "\n"
                              
          + "原因: " + RegExp.$5);
                      }

          三,提供一個跨瀏覽器的XML DOM對象解決方案,來自于《javascript高級程序設計》

          function XmlDom() {
              
          //通過對象/屬性檢測法,判斷是IE來是Mozilla
              if (window.ActiveXObject) {
                  
          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 is not installed on your system."); 
                     
              
          //同上          
              } else if (document.implementation && document.implementation.createDocument) {
                  
                  
          var oXmlDom = document.implementation.createDocument("","",null);

                  
          //創建Mozilla版本的parseError對象
                  oXmlDom.parseError = {
                      valueOf: 
          function () { return this.errorCode; },
                      toString: 
          function () { return this.errorCode.toString() }
                  };
                  
                  
          //初始化parseError對象
                  oXmlDom.__initError__();
                          
                  
                  oXmlDom.addEventListener(
          "load"function () {
                      
          this.__checkForErrors__();
                      
          this.__changeReadyState__(4);
                  }, 
          false);

                  
          return oXmlDom;        
                  
              } 
          else {
                  
          throw new Error("Your browser doesn't support an XML DOM object.");
              }
          }

          //此處用到了該書中一個瀏覽器系統檢測js文件,如果是Mozilla
          if (isMoz) {

              Document.prototype.readyState 
          = 0;
              Document.prototype.onreadystatechange 
          = null;

              
              Document.prototype.__changeReadyState__ 
          = function (iReadyState) {
                  
          this.readyState = iReadyState;

                  
          if (typeof this.onreadystatechange == "function") {
                      
          this.onreadystatechange();
                  }
              };
              
          //初始化parseError對象
              Document.prototype.__initError__ = function () {
                  
          this.parseError.errorCode = 0;
                  
          this.parseError.filepos = -1;
                  
          this.parseError.line = -1;
                  
          this.parseError.linepos = -1;
                  
          this.parseError.reason = null;
                  
          this.parseError.srcText = null;
                  
          this.parseError.url = null;
              };
              
              Document.prototype.__checkForErrors__ 
          = function () {

                  
          if (this.documentElement.tagName == "parsererror") {

                      
          var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;

                      reError.test(
          this.xml);
                      
                      
          this.parseError.errorCode = -999999;
                      
          this.parseError.reason = RegExp.$1;
                      
          this.parseError.url = RegExp.$2;
                      
          this.parseError.line = parseInt(RegExp.$3);
                      
          this.parseError.linepos = parseInt(RegExp.$4);
                      
          this.parseError.srcText = RegExp.$5;
                  }
              };
              
               
          //定義Mozilla的loadXML方法   
              Document.prototype.loadXML = function (sXml) {
              
                  
          this.__initError__();
              
                  
          this.__changeReadyState__(1);
              
                  
          var oParser = new DOMParser();
                  
          var oXmlDom = oParser.parseFromString(sXml, "text/xml");
           
                  
          while (this.firstChild) {
                      
          this.removeChild(this.firstChild);
                  }

                  
          for (var i=0; i < oXmlDom.childNodes.length; i++) {
                      
          var oNewNode = this.importNode(oXmlDom.childNodes[i], true);
                      
          this.appendChild(oNewNode);
                  }
                  
                  
          //載入后檢查錯誤
                  this.__checkForErrors__();
                  
                  
          //沒有問題,設置readyState屬性為4
                  this.__changeReadyState__(4);

              };
              
              Document.prototype.__load__ 
          = Document.prototype.load;

              Document.prototype.load 
          = function (sURL) {
                  
          this.__initError__();
                  
          this.__changeReadyState__(1);
                  
          this.__load__(sURL);
              };
              
              Node.prototype.__defineGetter__(
          "xml"function () {
                  
          var oSerializer = new XMLSerializer();
                  
          return oSerializer.serializeToString(this"text/xml");
              });

          }

          posted on 2009-04-30 15:46 王雪峰 閱讀(52) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          My Links

          Blog Stats

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章檔案

          搜索

          最新評論

          主站蜘蛛池模板: 紫阳县| 营口市| 南丰县| 博爱县| 北流市| 三门峡市| 开阳县| 岢岚县| 肇东市| 襄樊市| 茂名市| 大足县| 甘洛县| 舟曲县| 诸暨市| 稷山县| 德令哈市| 探索| 乐业县| 奈曼旗| 景谷| 定日县| 新邵县| 灵石县| 康定县| 和林格尔县| 濮阳县| 长春市| 邯郸县| 增城市| 石台县| 西林县| 交城县| 徐州市| 罗田县| 田阳县| 犍为县| 资阳市| 麻栗坡县| 裕民县| 肃北|