一個用xslt樣式將xml解析為xhtml的類TransformBinder(兼容FF和IE7.0)_Xml教程

      編輯Tag賺U幣
      教程Tag:XMLxhtmlxslt添加

      推薦:jscript與vbscript 操作XML元素屬性的代碼
      jscript與vbscript 操作XML元素屬性的代碼,需要的朋友可以參考下。

      由于前面的方法xslt需要在xml文件內部直接導入,而項目中用到的xml文件是系統生成的,只能提供路徑,而沒有辦法改寫xml里面的內容,所以需要找一個方法能夠在外部將xml和xslt關聯在一起,這樣既達到了目的,也可以應用于多個xml文件,方便管理。
      先上代碼,系統中使用module這個js進行打包,module這個工具是專門用來將js進行打包,這個工具以后的文章再做介紹,我自己現在只會使用,還沒研究其底層的代碼;這邊我們將js寫在一個文件里面,包括類以及類實現的方法,
      下面是js代碼:transform.js
      復制代碼 代碼如下:www.wf0088.com

      var XmlDom=function(){
      if (window.ActiveXObject) { // IE
      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.");
      } else if(document.implementation.createDocument){ // Firefox
      var oXmlDom = document.implementation.createDocument("", "", null);
      return oXmlDom;
      } else{
      throw new Error("瀏覽器不支持 XML DOM object.");
      }
      }
      var transformXSLT=function(_XML,_XSL) {
      if (window.Node) {
      Node.prototype.transformNode = function(XslDom) {
      var oProcessor = new XSLTProcessor();
      oProcessor.importStylesheet(XslDom);
      var oResultDom = oProcessor.transformToDocument(myXmlDom);
      var oSerializer = new XMLSerializer();
      var sXml = oSerializer.serializeToString(oResultDom, "text/xml");
      return sXml;
      }
      }
      var myXmlDom = new XmlDom();
      myXmlDom.async=false;
      var myXslDom = new XmlDom();
      myXslDom.async=false;
      myXmlDom.load(_XML);
      myXslDom.load(_XSL);
      var sResult=myXmlDom.transformNode(myXslDom);
      if(window.ActiveXObject){
      if(myXmlDom.parseError.errorCode != 0){
      var sError=myXmlDom.parseError;
      var txt = "";
      txt += "<br>錯誤代碼: ";
      txt += sError.errorCode;
      txt += "<br>錯誤原因: ";
      txt += sError.reason;
      txt += "<br>錯誤行號: ";
      txt += sError.line;
      document.write(txt);
      }else{
      document.write(sResult);
      }
      } else if(document.implementation.createDocument){
      var oSerializer = new XMLSerializer();
      var sXmlDom = oSerializer.serializeToString(myXmlDom, "text/xml");
      var oParser = new DOMParser();
      var oXmlDom = oParser.parseFromString(sXmlDom,"text/xml");
      if (oXmlDom.documentElement.tagName == "parsererror") {
      var oXmlSerializer = new XMLSerializer();
      var sXmlError = oXmlSerializer.serializeToString(oXmlDom);
      alert(sXmlError);
      } else {
      document.write(sResult);
      }
      }
      }
      var TransformBinder = function(XML,XSL) {
      this.XML = XML;
      this.XSL = XSL;
      }
      TransformBinder.prototype.registerAction = function(handlers) {
      this.handlers = handlers;
      }
      TransformBinder.prototype.bind = function() {
      var _this = this;
      this.handlers(_this.XML,_this.XSL);
      }

      下面是html代碼:XSLTtransform.htm
      復制代碼 代碼如下:www.wf0088.com

      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <script type='text/javascript' src="transform.js"></script>
      </head>
      <body>
      <script type="text/javascript">
      var XML = "這里輸入XML路徑";
      var XSL = "這里輸入XSL路徑";
      var tempObj = new TransformBinder(XML,XSL);
      tempObj.registerAction(transformXSLT);
      tempObj.bind();
      </script>
      </body>
      </html>

      分析一下transform.js:
      xmlDom這個構造函數是用來創建xml的dom元素,對于IE和FF,創建dom的方法不一樣,IE是用window.ActiveXObject這個方法來創建,而FF用document.implementation.createDocument這個方法來創建,我們用這兩個屬性來判斷是IE還是FF。
      IE下針對不同版本的xml["MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument","Microsoft.XmlDom"],用for循環進行遍歷查找到對應的版本再new ActiveXObject(arrSignatures[i])建立dom;
      FF下用document.implementation.createDocument("", "", null);直接創建dom ;
      如果瀏覽器不支持 XML DOM object則throw錯誤 。
      transformXSLT這個構造函數用XSLT將xml轉換成html,FF下沒有transformNode這個方法,所以我們自己構造了一個方法,
      復制代碼 代碼如下:www.wf0088.com

      Node.prototype.transformNode = function(XslDom) {
      var oProcessor = new XSLTProcessor();
      oProcessor.importStylesheet(XslDom);
      var oResultDom = oProcessor.transformToDocument(myXmlDom);
      var oSerializer = new XMLSerializer();
      var sXml = oSerializer.serializeToString(oResultDom, "text/xml");
      return sXml;
      }

      然后用這個方法實現轉換,在處理錯誤上IE和FF又有不同的處理方法,IE比較簡單,有一個parseError屬性裝載錯誤信息,errorCode是錯誤的代碼,reason是錯誤原因,line是錯誤的行號,還有其他一些信息,這里只要顯示主要的錯誤信息就可以了,如果出錯了就顯示出錯內容,如果沒有出錯則顯示轉換的結果sResult。FF下就比較復雜一點,用XMLSerializer和XMLSerializer.serializeToString()將xmlDom轉換為字符串,再將字符串轉換成dom對象,在轉換的過程中如果報錯,就能得到包含有parsererror的信息,判斷得到的字符串的tagName是不是parsererror,如果是則將dom對象再轉換成字符串拋出字符串中的內容,如果不是則顯示轉換的結果sResult。
      這里有幾個注意點:
      a.IE能檢驗出XML的DTD錯誤,而FF下只能檢驗出XML本身的語法錯誤;
      b.因為需要在瀏覽器下判斷錯誤,最終的結果不好合并,可能代碼結構上看起來不太合理,這也是無奈之舉。
      用TransformBinder這個類進行封裝,便于擴展和修改。TransformBinder.prototype.registerAction這個原型用于注冊事件,再用TransformBinder.prototype.bind將事件進行綁定,需要使用這個類的時候,只需要new TransformBinder(XML,XSL),注冊transformXSLT事件,再bind進行綁定,這樣就實現這個效果了。如果需要擴展,再創建新的構造函數,注冊并綁定到這個類上就可以實現效果。

      分享:XML解析錯誤:未組織好 的解決辦法
      主要問題:XML文件完整,在liunx系統下可正常顯示,但是windows系統提示出錯

      來源:模板無憂//所屬分類:Xml教程/更新時間:2013-04-22
      相關Xml教程