Pull to refresh

AJAX + XML + XSLT или новый взгяд на AJAX

Reading time5 min
Views792
Года полтора назад встала проблема в динамическом генерировании HTML кода. Отстраивать HTML посредством DOM слишком громоздко и код получается большой, подгружать сгенерированный HTML на сервере, не очень красивое и харкодное решение.
Было принято решение искать альтернативный способ генерации HTML.
И оно было найдено: AJAX + XML + XSLT.
НА стороне сервера лежит XSLT шаблон, скрипт который генерирует XML (или XML файл). НА стороне клиента посредством AJAX загружается XML и XSLT и преобразуется в HTML

Пример использования:
  1. function getContent(){
  2.   try{
  3.     var xslt = new xsltLoad("http://"+location.hostname+"/content.xml,   "http://"+location.hostname+"/template.xsl", "myDiv", callback);
  4.   xslt.init();
  5.   }catch(e){
  6.   alert(e.message)
  7.   }
  8. }
* This source code was highlighted with Source Code Highlighter.


myDiv — элемент в который будет вставлен наш HTML
callback — функция обратного вызова, которая отработает после загрузки контента.
Плюсы: Минимализация загружаемых данных с сервера, разгрузка сервера при генерации HTML, в данном случае эта операции перекладывается на компьютер клиента.
Минусы данного метода: некорректно работает в браузерах Опера и Сафари при парсинге XSLT шаблонов содержищие сложные инструкции типа for-each

Ну и сам код который реализует эту связку:
  1. function getXmlHttpRequestObject() {
  2.   if (window.XMLHttpRequest) {
  3.     try {
  4.       var receiveReq = new XMLHttpRequest();
  5.     } catch (e){}
  6.   } else if (window.ActiveXObject) {
  7.     var xmlHttpVers = new Array('Msxml2.XMLHTTP.6.0','Msxml2.XMLHTTP.5.0','Msxml2.XMLHTTP.4.0','Msxml2.XMLHTTP.3.0','Msxml2.XMLHTTP','Microsoft.XMLHTTP');
  8.     for(var i = 0; i < xmlHttpVers.length && !receiveReq; i++){
  9.       try{
  10.          var receiveReq = new ActiveXObject(xmlHttpVers[i]);
  11.       }catch(e){}
  12.     }
  13.   }
  14.   return receiveReq;
  15. }
  16.  
  17. function __callXmlHttprequest(r, f){
  18.   if(r.readyState == 4 && r.status == 200){
  19.     f(r);
  20.   }
  21. }
  22.  
  23. function getReceive(url, funcCallback, l){
  24.   if(!l){
  25.       l = true;
  26.   }
  27.   var xmlHttp = getXmlHttpRequestObject();
  28.   if(!xmlHttp){
  29.     return;
  30.   }
  31.   if(funcCallback){
  32.     xmlHttp.onreadystatechange = function(){
  33.       __callXmlHttprequest(xmlHttp, funcCallback);
  34.     };
  35.   }else{
  36.     xmlHttp.onreadystatechange = function(){};
  37.   }
  38.   xmlHttp.open("GET", url, l);
  39.     xmlHttp.send(null);
  40. }
  41.  
  42. var Browser = {
  43.   IE:   !!(window.attachEvent && !window.opera),
  44.   Opera: !!window.opera,
  45.   Khtml: navigator.userAgent.indexOf('AppleWebKit/') > -1,
  46.   Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
  47. }
  48.  
  49. function xsltLoad(xmlFile, xsltFile, elementId, _call){
  50.   var method;
  51.   var postData;
  52.   var stylesheetDoc;
  53.   var xmldoc, xsldoc;
  54.  
  55.   this.createMSDOM = function(){
  56.     var msdom;
  57.     var v = new Array("Msxml2.DOMDocument.6.0","Msxml2.DOMDocument.5.0","Msxml2.DOMDocument.4.0");
  58.     for (var i=0; i< v.length && !msdom; i++) {
  59.       try {
  60.         msdom = new ActiveXObject(v[i]);
  61.       } catch (e) {}
  62.     }
  63.     return msdom;
  64.   }
  65.  
  66.   this.init = function(){
  67.     if(Browser.IE){
  68.       xmldoc = new ActiveXObject("Microsoft.XMLDOM");
  69.       xmldoc.async = false;
  70.       xmldoc.load(xmlFile);
  71.  
  72.       xsldoc = new ActiveXObject("Microsoft.XMLDOM");
  73.       xsldoc.async = false;
  74.       xsldoc.load(xsltFile);
  75.       document.getElementById(elementId).innerHTML = xmldoc.transformNode(xsldoc);
  76.       if(_call){
  77.           _call();
  78.         }
  79.     }else{
  80.       this.loadStylesheet();
  81.       this.loadXMLFile();
  82.       return;
  83.     }
  84.   }
  85.   this.callBack = function(r){
  86.     try{
  87.        var dp = new DOMParser();
  88.       stylesheetDoc = dp.parseFromString(r.responseText, "text/xml");
  89.     }catch(e){
  90.       alert(e)
  91.     }
  92.   }
  93.  
  94.   this.loadStylesheet = function(){
  95.     getReceive(xsltFile+"?"+randomNumber(1,999999), this.callBack, false);
  96.   }
  97.  
  98.   this.loadXMLFile = function(){
  99.     if(!method){
  100.       getReceive(xmlFile, this.buildHTML);
  101.     }else{
  102.       getReceive(xmlFile, encodeURIComponent(this.postData), this.buildHTML);
  103.     }
  104.   }
  105.  
  106.   this.buildHTML = function(r){
  107.     xmlResponse = r.responseXML;
  108.     try{
  109.       var xsltProcessor = new XSLTProcessor();
  110.           xsltProcessor.importStylesheet(stylesheetDoc);
  111.           page = xsltProcessor.transformToFragment(xmlResponse, document);
  112.           var e = document.getElementById(elementId);
  113.          e.innerHTML = "";
  114.          e.appendChild(page);
  115.          stylesheetDoc = null;
  116.          xsltProcessor = null;
  117.     }catch(e2){
  118.       alert(e2.message);
  119.     }
  120.       if(_call){
  121.         _call();
  122.       }
  123.   }
  124. }
* This source code was highlighted with Source Code Highlighter.

Tags:
Hubs:
Total votes 14: ↑9 and ↓5+4
Comments11

Articles