首頁  >  文章  >  後端開發  >  類別TransformBinder將xml解析為xhtml的實例方法

類別TransformBinder將xml解析為xhtml的實例方法

Y2J
Y2J原創
2017-04-22 14:20:341481瀏覽

這幾天一直在研究xslt轉換xml為xhtml,前面文章有介紹使用xslt將xml解析成xhtml 的文章

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

程式碼如下:

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

 程式碼如下:

<!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=&#39;text/javascript&#39; 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這個方法,所以我們自己建構了一個方法,

 程式碼如下:

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進行綁定,這樣就實現這個效果了。如果需要擴展,再建立新的建構函數,註冊並綁定到這個類別上就可以實現效果。

以上是類別TransformBinder將xml解析為xhtml的實例方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn