漂泊的云

          javascript之XML DOM對(duì)象

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

          一 IE中的XML DOM
          1.微軟通過(guò)ActiveX的MSXML庫(kù)提供了支持,通過(guò):
           var oXmlDom = new ActiveXObject("MSXML2.DOMDocument.5.0")
          得到一個(gè)XML DOM對(duì)象,這是在IE6中的,如果你的IE是更老版本的,可以使用下面的函數(shù)得到,如果你沒(méi)有安裝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("你的系統(tǒng)沒(méi)有安裝MSXML");           
                  }     

          當(dāng)然,如果你使用prototype庫(kù),可以使用Try.these函數(shù)。

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

          3.XML DOM默認(rèn)是通過(guò)異步載入xml文件的,可以通過(guò)設(shè)置async值來(lái)選擇是同步還是異步:
          oXmlDom.async=true;


          4.
          IE的XML DOM擁有一個(gè)readyState值用來(lái)表示載入文件的狀態(tài):

          0——準(zhǔn)備載入
          1——正在載入
          2——載入完成
          3——載入完成并可用,但有一部分?jǐn)?shù)據(jù)也許不可用
          4——完全載入,完全可用。

          相應(yīng)的有一個(gè)onreadystatechange事件,當(dāng)狀態(tài)改變時(shí)發(fā)生,我們可以通過(guò)監(jiān)聽(tīng)此事件來(lái)判斷XML DOM對(duì)象的可用性
          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對(duì)象有一個(gè)xml屬性,用來(lái)返回xml文件的字符串形式,比如
          oXmlDom.async=false;
          oXmlDom.load(
          "test.xml");
          alert(oXmlDom.xml);

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

          6.IE,當(dāng)載入的XML文件或者字符串解析錯(cuò)誤時(shí),將產(chǎn)生一個(gè)parseError對(duì)象,我們?cè)谙旅娴拇a中演示此對(duì)象的屬性:
                      oXmlDom.async = false;
                      oXmlDom.load(
          "errors.xml");
                      
                      
          //0表示沒(méi)有錯(cuò)誤
                      if (oXmlDom.parseError != 0) {
                          
          var oError = oXmlDom.parseError;
                      
                          alert(
          "An error occurred:\n錯(cuò)誤代碼: "
                                
          + oError.errorCode + "\n"
                                
          + "行數(shù): " + oError.line + "\n"
                                
          + "列數(shù): " + oError.linepos + "\n"
                                
          + "原因: " + oError.reason);
                                
                      }


          二.Mozilla的XML DOM對(duì)象
          1.XML DOM對(duì)象的創(chuàng)建,符合DOM標(biāo)準(zhǔn)的,通過(guò)document.implementation.createDocument()方法。比如:
          var oXmlDom=document.implementation.createDocument("","",null);

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

          這段代碼創(chuàng)建了一個(gè)<a0:root xmlns="http://www.rubyeye.net"/>的XML DOM對(duì)象


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

          異步載入稍有不同,因?yàn)镸ozilla并不支持readyState屬性,并且沒(méi)有onreadystatechange事件,它只有一個(gè)onload的事件,當(dāng)載入完成時(shí)觸發(fā);或者說(shuō)相當(dāng)于IE的readyState屬性等于4的狀態(tài)。
          oXmlDom.onload=function(){
          alert(
          "done");
          }
          oXmlDom.load(
          "test.xml");

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

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

          3.Mozilla沒(méi)有提供IE的xml屬性來(lái)返回XML文檔內(nèi)容,只能通過(guò)使用XMLSerializer對(duì)象:
          var oSerializer=new XMLSerializer();
          var sXml=oSerializer.serializeToString(oXmlDom,"text/xml");
          同樣兩個(gè)參數(shù):XML DOM對(duì)象以及轉(zhuǎn)化成的文檔類(lèi)型。

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

          以后就可以以IE的方式,oXmlDom.xml來(lái)獲取XML文檔內(nèi)容。

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

          三,提供一個(gè)跨瀏覽器的XML DOM對(duì)象解決方案,來(lái)自于《javascript高級(jí)程序設(shè)計(jì)》

          function XmlDom() {
              
          //通過(guò)對(duì)象/屬性檢測(cè)法,判斷是IE來(lái)是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);

                  
          //創(chuàng)建Mozilla版本的parseError對(duì)象
                  oXmlDom.parseError = {
                      valueOf: 
          function () { return this.errorCode; },
                      toString: 
          function () { return this.errorCode.toString() }
                  };
                  
                  
          //初始化parseError對(duì)象
                  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.");
              }
          }

          //此處用到了該書(shū)中一個(gè)瀏覽器系統(tǒng)檢測(cè)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對(duì)象
              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);
                  }
                  
                  
          //載入后檢查錯(cuò)誤
                  this.__checkForErrors__();
                  
                  
          //沒(méi)有問(wèn)題,設(shè)置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) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          My Links

          Blog Stats

          常用鏈接

          留言簿(2)

          隨筆分類(lèi)

          隨筆檔案

          文章檔案

          搜索

          最新評(píng)論

          主站蜘蛛池模板: 连江县| 巫山县| 连城县| 太仓市| 万年县| 云和县| 濉溪县| 乌审旗| 永宁县| 江津市| 遂昌县| 台北县| 齐齐哈尔市| 收藏| 鞍山市| 监利县| 辰溪县| 盈江县| 略阳县| 扎囊县| 伊宁市| 上思县| 麻江县| 白朗县| 汤阴县| 洪泽县| 庆城县| 巴中市| 宿州市| 岚皋县| 桦甸市| 康定县| 南雄市| 兰州市| 大连市| 屏南县| 邓州市| 禄丰县| 泸西县| 沙湾县| 响水县|