莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          javascript之XML DOM對象

          Posted on 2007-03-09 10:21 dennis 閱讀(4280) 評論(1)  編輯  收藏 所屬分類: web開發(fā)
          javacript中對xml dom的支持,與其他任何特性一樣面臨著瀏覽器兼容問題。

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

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

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

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


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

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

          相應的有一個onreadystatechange事件,當狀態(tài)改變時發(fā)生,我們可以通過監(jiān)聽此事件來判斷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文件或者字符串解析錯誤時,將產(chǎn)生一個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"
          ??????????????????????
          +?"行數(shù):?"?+?oError.line?+?"\n"
          ??????????????????????
          +?"列數(shù):?"?+?oError.linepos?+?"\n"
          ??????????????????????
          +?"原因:?"?+?oError.reason);
          ??????????????????????
          ????????????}


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

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

          這段代碼創(chuàng)建了一個<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的事件,當載入完成時觸發(fā);或者說相當于IE的readyState屬性等于4的狀態(tài)。
          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");

          兩個參數(shù):要解析的XML字符串以及字符串的內(nèi)容類型(只能為text/xml或者application/xml)。
          不過我們可以實現(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);
          ????????????}
          ????????????
          //導入新的文檔內(nèi)容
          ????????????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文檔內(nèi)容,只能通過使用XMLSerializer對象:
          var?oSerializer=new?XMLSerializer();
          var?sXml=oSerializer.serializeToString(oXmlDom,"text/xml");
          同樣兩個參數(shù):XML DOM對象以及轉(zhuǎn)化成的文檔類型。

          同樣,我們也可以給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文檔內(nèi)容。

          4。錯誤處理,同樣與IE不同,Mozilla當解析錯誤時會返回一段代碼,以標簽<prasereoor>包括其中的代碼解釋了錯誤發(fā)生的原因以及位置等信息,我們只有通過正則表達式解析此段代碼,提取錯誤信息。
          ????? var?reError?=?/>([\s\S]*?)Location:([\s\S]*?)Line?Number?(\d+),?Column?(\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
          ???????????
          ????????????
          //返回代碼的標簽名為parsererror,表示錯誤發(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);
          ????????????}

          三,提供一個跨瀏覽器的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);

          ????????
          //創(chuàng)建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.");
          ????}
          }

          //此處用到了該書中一個瀏覽器系統(tǒng)檢測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");
          ????});

          }


          評論

          # re: javascript之XML DOM對象  回復  更多評論   

          2007-03-19 11:46 by dennis
          附帶說明下,在Mozilloa,上文所提的處理錯誤的方法是行不通的,因為Mozilla返回的說明錯誤的文字是隨平臺的字符編碼而改變的,比如在中文平臺上將顯示中文錯誤信息,想通過正則表達式提取這個信息來實現(xiàn)類似IE的錯誤處理是不可能的
          主站蜘蛛池模板: 新干县| 漾濞| 遂昌县| 二手房| 湘乡市| 普陀区| 陇南市| 金堂县| 旬阳县| 休宁县| 马尔康县| 阳山县| 嘉黎县| 渭南市| 家居| 夏河县| 布拖县| 香格里拉县| 长宁区| 东海县| 高州市| 江北区| 商城县| 临沭县| 五河县| 建宁县| 托克托县| 本溪市| 昭苏县| 登封市| 建阳市| 天水市| 惠东县| 英超| 进贤县| 泗水县| 鹤庆县| 凤庆县| 陇川县| 盐亭县| 巴东县|