From ba9f8b7e732ab1d78dff54ca0f4e0bdf79a5c9fe Mon Sep 17 00:00:00 2001 From: Danielside Date: Sun, 29 Dec 2019 14:24:16 +0100 Subject: [PATCH] gitlab --- README.md | 19 + jquery.ajaxslt.js | 658 ++++++++++++++++++++++++++++ test_module/cp.php | 152 +++++++ test_module/test_response_xml.xml | 25 ++ test_module/test_response_xml_2.xml | 22 + test_module/test_response_xsl.xml | 52 +++ test_module/test_response_xsl_2.xml | 32 ++ util.js | 17 + 8 files changed, 977 insertions(+) create mode 100644 README.md create mode 100644 jquery.ajaxslt.js create mode 100644 test_module/cp.php create mode 100644 test_module/test_response_xml.xml create mode 100644 test_module/test_response_xml_2.xml create mode 100644 test_module/test_response_xsl.xml create mode 100644 test_module/test_response_xsl_2.xml create mode 100644 util.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..3858d2d --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# AjaXSLT +jQuery plugin to create user interfaces using Ajax, XML and XSLT transformations on the client-side. +The project is about both the client side and the server side, so the server must send and receive appropiate messages. + +Have a look at test_module/cp.php. This a PHP server-side script but nothing prevents you from using another language in the server: Python, Ruby, Java... as long as you send the client engine the expected XML/XSLT messages through Ajax. + +# Demo +Here: http://danielside.nom.es/ajaxslt/test_jquery_xslt_es.php + +# Remarks +This project was conceived some 7 years ago and I don't know if it works well on modern browsers, but I have checked with a current Firefox and it works as a charm. + +# Sort of documentation (Spanish) +http://danielside.nom.es/2010/04/23/jquery-y-ajax-transformaciones-xslt-en-el-navegador/ +and +http://danielside.nom.es/2010/04/29/libreria-jquery-y-ajax-para-transformaciones-xslt-en-el-navegador-ii/ + +# Test module +Under the the directory test_module there is a handful of PHP, XML and XSLT files to test this project out, you only need to drop jQuery and you are ready to go. The project is tested with jQuery 1.3.2 but maybe it is worth trying the current -or a modern- version. \ No newline at end of file diff --git a/jquery.ajaxslt.js b/jquery.ajaxslt.js new file mode 100644 index 0000000..89a8825 --- /dev/null +++ b/jquery.ajaxslt.js @@ -0,0 +1,658 @@ +;(function( $ ) { + + + $.fn.ajaxslt = function ( controller_request, parameters_for_request, parameters_for_xslt, callbacks ) { + + var def = $.fn.ajaxslt.defaults; + + var module = controller_request.module; + var webservice = controller_request.webservice; + var action = controller_request.action; + var force_reload_xml = controller_request.force_reload_xml; + + var ajaxDataType = 'xml'; + if ( !( controller_request.ajax_data_type === undefined ) ) { + ajaxDataType = controller_request.ajax_data_type; + } + + var target = $( this ); + + if ( !module || !webservice || !action ) return false; + + if ( force_reload_xml === undefined ) force_reload_xml = true; + if ( parameters_for_request === undefined ) parameters_for_request = {}; + if ( callbacks === undefined ) callbacks = {}; + + var parametros = {}; + + jQuery.each ( parameters_for_request , function ( index_name, value ) { + parametros [ index_name ] = value; + }); + + var objetoCacheXSLT = CacheXSLT; + var objetoCacheXML = CacheXML; + + parametros['_M_'] = module; + parametros['_W_'] = webservice; + parametros['_A_'] = action; + + //Consultas a la cache de XML y XSLT en busca de elementos cacheados anteriormente + var fallo_en_cache_xslt = def.CACHE_LOCAL_FOUND; + var fallo_en_cache_xml = def.CACHE_LOCAL_FOUND; + + var id_cache = construirIdCache( module, webservice ); + //Gestionar fallos en la cache para pedir el xsl si no lo tenemos + + if ( objetoCacheXSLT.buscar_por_identificador( id_cache ) == -1 ) { + fallo_en_cache_xslt = def.CACHE_LOCAL_NOT_FOUND; + } + + var busca_accion = objetoCacheXML.buscar_por_identificador_y_accion( id_cache, action ); + if ( busca_accion[0] == -1 || busca_accion[1] == -1 ) { + fallo_en_cache_xml = def.CACHE_LOCAL_NOT_FOUND; + } else { + if ( force_reload_xml ) { + fallo_en_cache_xml = def.CACHE_LOCAL_FOUND_BUT_SEND; + } + } + + parametros['_FXS_'] = fallo_en_cache_xslt; + parametros['_FXM_'] = fallo_en_cache_xml; + + var fallo_en_cache_global = ( fallo_en_cache_xml == def.CACHE_LOCAL_NOT_FOUND ) || + ( fallo_en_cache_xml == def.CACHE_LOCAL_FOUND_BUT_SEND ) || + ( fallo_en_cache_xslt == def.CACHE_LOCAL_NOT_FOUND ); + + + if ( fallo_en_cache_global ) { + jQuery.ajax ( { + url: def.APPLICATION_DIRECTORY + module + '/' + def.WEBSERVICES_CONTROLLER, + data: parametros, + dataType: ajaxDataType, + global: true, + timeout: 15000, + type: 'POST', + async: true, + cache: false, + success: function ( data, textStatus ) { + + jQuery( data ).find( def.XML_DEF_ROOT ).children().each ( function (){ + + if ( jQuery(this).is ( def.XML_DEF_ROOT_CONTROL )) { + + }//fin secc control + + var x_module; + var x_webservice; + var x_accion; + var contenido; + + if ( jQuery( this ).is( def.XML_DEF_ROOT_DATA )) { + + jQuery( this ).children().each ( function() { + var $thischild = jQuery( this ); + + if ( $thischild.is( def.XML_DEF_ROOT_DATA_XSLT ) ) { + x_module = jQuery( this ).attr( def.XML_DEF_ATTR_MODULE ); + x_webservice = jQuery( this ).attr( def.XML_DEF_ATTR_WEBSERVICE ); + var identificador_local = jQuery( this ).attr( def.XML_DEF_ATTR_IDLOCAL ); + + contenido = jQuery( this ); + var contenido_text = jQuery.trim( contenido.text() ); + + if ( contenido_text.length > 0 ) //Este test evita machacar un contenido cacheado + { + + var xsl_compuesto = CacheXSLT.pre_xsl; + xsl_compuesto = xsl_compuesto.concat ( contenido_text ); + xsl_compuesto = xsl_compuesto.concat ( CacheXSLT.post_xsl ); + var xsl_doc = XML.XSLdesdeTexto( xsl_compuesto ); + + try { + if ( jQuery.isFunction( callbacks.fn_xsl_server_loaded ) ) callbacks.fn_xsl_server_loaded( xsl_doc ); + } catch ( e ) {ajx_debug('Callback xsl server loaded', e);} + + objetoCacheXSLT.guardar( construirIdCache( x_module, x_webservice ), xsl_doc, identificador_local ); + } + }//fin seccion xslt + + + + if ( $thischild.is( def.XML_DEF_ROOT_DATA_XML ) ) { + x_modulo = jQuery(this).attr( def.XML_DEF_ATTR_MODULE ); + x_webservice = jQuery(this).attr( def.XML_DEF_ATTR_WEBSERVICE ); + x_accion = jQuery(this).attr( def.XML_DEF_ATTR_ACTION ); + + contenido = jQuery(this); + var contenido_text = jQuery.trim( contenido.text() ); + + var identificador = construirIdCache ( x_modulo, x_webservice ); + + if ( contenido_text.length > 0 ) //Este test evita machacar un contenido cacheado + { + var xml_doc = XML.XMLdesdeTexto( def.XML_PRE.concat( contenido_text ) ); + objetoCacheXML.guardar ( identificador, x_accion, xml_doc, target ); + + try { + if ( jQuery.isFunction( callbacks.fn_xml_server_loaded ) ) callbacks.fn_xml_server_loaded( xml_doc ); + } catch ( e ) {ajx_debug('Callback xml server loaded', e);} + + var callback_fn_xsl_cache_loaded = undefined; + if ( !( fallo_en_cache_xslt == def.CACHE_LOCAL_NOT_FOUND ) ) { + callback_fn_xsl_cache_loaded = callbacks.fn_xsl_cache_loaded + } + + procesador.volcar( objetoCacheXSLT.procesar(xml_doc, + identificador, + parameters_for_xslt, + callback_fn_xsl_cache_loaded), + target ); + } + }//fin seccion xml-app + + + + if ( $thischild.is( def.XML_DEF_ROOT_DATA_JS ) ) { + try + { + //Si viene un deplib cargar y como callback hacer el eval y + //si no directamente hacer el eval + var dep_lib = jQuery( this ).attr( def.XML_DEF_ROOT_DATA_JS_ATTR_DEP_LIB ); + var to_eval = jQuery( this ).text(); + if ( dep_lib != undefined ) { + //TO-DO probar jQuery.globalEval + var res = jQuery.getScript( dep_lib, function(){ + eval( to_eval ); + }); + //Esto solo se ejecutara si la peticion getScript se da cuenta de que no tiene que traer el script + if ( res == false ){ + eval( to_eval ); + } + } + else { + eval( to_eval ); + } + + } + catch( e ){ajx_debug( 'Obtaining and evaluating js from server', e );} + }//fin seccion js + + });//fin each hijos de secc datos + } //fin seccion datos del xml + }); //fin jQuery each itera xml + + + try { + if ( jQuery.isFunction( callbacks.fn_success ) ) callbacks.fn_success(); + } catch ( e ) {ajx_debug( 'Callback success', e );} + + } //end success + + }); //fin ajax + + } + else //of "if ( fallo_en_cache_global )" + { + //Acierto en la cache global (en las dos = global) + //pintar buscando contenidos en la cache + var posicion = objetoCacheXML.buscar_por_identificador_y_accion( id_cache, action ); + var pos_id = posicion[0]; + var pos_ac = posicion[1]; + + if ( pos_id != -1 && pos_ac != -1 ) { + + var xml_doc = objetoCacheXML.cache[pos_id][1][pos_ac][1].texto; + + //callbacks + try { + if ( jQuery.isFunction ( callbacks.fn_xml_cache_loaded ) ) callbacks.fn_xml_cache_loaded( xml_doc ); + } catch( e ) {ajx_debug( 'Callback xml cache loaded', e );} + + procesador.volcar( objetoCacheXSLT.procesar( xml_doc, id_cache, parameters_for_xslt, callbacks.fn_xsl_cache_loaded ), + target ); + + try { + if ( jQuery.isFunction( callbacks.fn_success ) ) callbacks.fn_success(); + }catch( e ) {ajx_debug( 'Callback success', e );} + } else { + ajx_debug( 'Obtaining xml from cache', 'Cache hit but problems obtaining xml' ); + } + } + + return false; + }; + + + $.fn.ajaxslt.defaults = { + APPLICATION_DIRECTORY: '/ajaxslt/', + WEBSERVICES_CONTROLLER: 'cp.php', + + XML_PRE: '', + XSLT_PRE: '', + XSLT_POST:'', + + CACHE_LOCAL_FOUND: '1', + CACHE_LOCAL_NOT_FOUND: '2', + CACHE_LOCAL_FOUND_BUT_SEND: '3', + + XML_DEF_ROOT:'framework', + XML_DEF_ROOT_CONTROL:'control', + XML_DEF_ROOT_DATA:'data', + XML_DEF_ROOT_DATA_XSLT:'xslt_data', + XML_DEF_ROOT_DATA_XML:'xml_data', + XML_DEF_ROOT_DATA_JS:'js_data', + XML_DEF_ROOT_DATA_JS_ATTR_DEP_LIB:'js_library', + XML_DEF_ATTR_MODULE:'module', + XML_DEF_ATTR_WEBSERVICE:'webservice', + XML_DEF_ATTR_ACTION:'action', + XML_DEF_ATTR_IDLOCAL:'local_id' + }; + + function construirIdCache ( mod, ws ) { return (mod.concat( '/' )).concat( ws ); }; + + function item_cache_xml ( t, d ) { this.texto=t;this.destino=d; }; + + + /* + * Los documentos xml que se gestionan aqui se guardan a nivel de modulo, accion. + */ + var CacheXML = { + /* + * un elemento de la cache es un array [modulo, array_acciones ] + * donde en array_acciones cada entrada es [accion, doc_xml_texto] + * Esta cache tiene la estructura: + * cache[i]: modulo i + * cache[i][0]: nombre del modulo i + * cache[i][1]: acciones del modulo i + * cache[i][1][j]: accion j del modulo i + * cache[i][1][j][0]: nombre de la accion j del modulo i + * cache[i][1][j][1]: xml de la accion j del modulo i + */ + cache:[], + tam_maximo:15, + + /* + * identificador Nombre del modulo + * accion Nombre de la accion + * texto XML serializado para guardar + */ + guardar: function( identificador, accion, xml_doc, destino ){ + //pos sera un array [posicion del modulo, posicion de la accion] + var pos = this.buscar_por_identificador_y_accion( identificador, accion ); + var pos_id = pos[0]; + var pos_ac = pos[1]; + + //var item = new item_cache_xml( texto, destino ); + + var item = new item_cache_xml ( xml_doc, destino ); + + if ( pos_id != -1 ) { + if ( this.tam_actual() < this.tam_maximo ) { + if (pos_ac != -1) { + + //Esta el modulo y la accion y hay espacio. Sustitucion. + this.cache[pos_id][1][pos_ac][1] = item; + } else { + + //Esta el modulo pero no la accion y hay espacio. Inserta accion. + this.cache[pos_id][1].push( [accion, item] ); + } + } else { + if (pos_ac != -1) { + + //Esta el modulo y la accion y no hay espacio. Desaloja accion. + this.cache[pos_id][1][pos_ac][0] = accion; + this.cache[pos_id][1][pos_ac][1] = item; + } else { + + //Esta el modulo pero no la accion y no hay espacio. Desaloja accion + this.cache[pos_id][1][0][0] = accion; + this.cache[pos_id][1][0][1] = item; + } + } + }else { + var array_acciones = Array(); + if ( this.tam_actual() < this.tam_maximo ) { + //No esta modulo y hay espacio. Crea modulo y accion. + this.cache.push( [identificador, array_acciones] ); + this.cache[this.cache.length-1][1][0] = [accion, item]; + + } else { + //No esta modulo y no hay espacio. Desaloja modulo. + this.cache[0] = [identificador, array_acciones]; + this.cache[0][1][0] = [accion, item]; + } + } + }, + + //busca en la cache y devuelve la posicion + buscar_por_identificador_y_accion: function ( identificador, accion ) { + var pos_id = -1; + + for (var i=0; i= 0 ){ //Substitution + this.cache[ pos ][ 1 ] = texto_xsl; + } + else{ //full? + if ( this.cache.length < this.tam_maximo ) { + //Vamos que queda hueco! + this.cache.push( [identificador, texto_xsl] ) ; + } else { + //A tope. Desalojar uno + this.cache[ 0 ] = [identificador, texto_xsl]; + } + } + }, + + + /* + * texto: documento xml para transformar + * identificador: identificador (==modulo) de la hoja xsl que necesita + */ + procesar: function( xml_doc, identificador, parameters_for_xslt, callback_fn_xsl_cache_loaded ){ + try{ + //Seguro que esta porque ya antes se han encargado (en Ajax) de gestionar posible fallo en cache + var posicion = this.buscar_por_identificador( identificador ); + var stored_xsl = this.cache[posicion][1]; + + try { + if ( jQuery.isFunction ( callback_fn_xsl_cache_loaded ) ) callback_fn_xsl_cache_loaded( stored_xsl ); + }catch( e ) { + ajx_debug( 'Callback for xsl cache loaded event', e ); + } + + this.procesador = new ProcesadorXSLT( stored_xsl ); + + return this.procesador.transformar( xml_doc, parameters_for_xslt ); + + } + catch ( e ){ + ajx_debug( 'CacheXSLT.procesar ', e ); + } + + + }, + + //busca en la cache y devuelve la posicion + buscar_por_identificador: function (identificador) { + var pos = -1; + + for (var i=0; i < this.cache.length; i++){ + if ( this.cache[i][0]==identificador ){ + pos = i; + break; + } + } + return pos; + }, + + limpiar: function () { + this.cache = []; + } + }; + + + function ProcesadorXSLT(){ + + this._preparado = false; + this._parametros = new Array(); + this._modo_debug = true; + + this.volcar = function( documento, $destino ){ + + $destino.each ( function () { + $( this ).empty().append( documento ); + }); + return true; + } + + if ( !jQuery.browser.msie ){ + + this._procesador = null; + + /* + * Carga un documento XML que contiene una hoja de estilo XSL + * xml - Documento XSL Stylesheet + */ + this.cargar = function( xml ){ + + try{ + this._procesador = new XSLTProcessor(); + this._procesador.importStylesheet(xml); + this._preparado = true; + }catch( e ) { ajx_debug ( 'ProcesadorXSLT.cargar', e ); } + + }; + + /* + * Transforma un documento XML usando this._procesador + * xml - documento XML a transformar + * throws 'Procesador XSLT no inicializado' si el procesador no esta correctamente inicializado y + * con la hoja de estilo XSL cargada + */ + this.transformar = function( xml, parametros ){ + if (!this._preparado) throw "XSLT processor not initialized"; + + this._procesador.clearParameters(); + var super_o = this; + + if ( !( parametros === undefined )) { + jQuery.each( parametros, function(i, item) { + super_o._procesador.setParameter(null, i, item); + } + ); + } + + var doc = document.implementation.createDocument( "", "", null ); + var fragmento = this._procesador.transformToFragment( xml, doc ); + + return fragmento; + } + + + } //fin moz + + + else if ( jQuery.browser.msie ){ + + this._procesador = null; + + this.cargar = function(xml){ + var xsltEngine = null; + try{ + xsltEngine = new ActiveXObject("Msxml2.XSLTemplate.3.0"); + }catch(e){ + } + if (xsltEngine != null) { + xsltEngine.stylesheet = xml; + this._procesador = xsltEngine.createProcessor(); + if (this._procesador) this._preparado = true; + } + }; + + this.transformar = function(xml, parametros){ + if (!this._preparado) throw "Procesador de XSLT no inicializado"; + this._procesador.input = xml; + + var super_o = this; + if ( !( parametros === undefined )) { + jQuery.each( parametros, function(i, item) { + super_o._procesador.addParameter(i, item); + }); + } + + this._procesador.transform(); + return this._procesador.output; + + }; + + + }; + + this.transformar_y_volcar = function(xml, destino, parametros){ + if (!parametros) parametros = {}; + return this.volcar(this.transformar(xml, parametros), destino); + }; + + + //Codigo principal + if ( arguments.length == 1 ) this.cargar( arguments[0] ); + + }; + var procesador = new ProcesadorXSLT(); + + + /* +* Esta libreria carga documentos XML con nodos (no texto), preparado de este modo para recuperar +* un documento XML desde una cadena o desde una URI. +* Carga documentos xml y xsl +* +* XMLdesdeTexto(cadena xml serializado) Crea xml dom desde xml serializado pasado +* XSLdesdeTexto(cadena xml serializado) Crea xsl dom desde xsl serializado pasado +*/ + var XML = { + + _modo_debug: false, + + XMLdesdeTexto: function( cadena ){ + + + + var doc; + if ( !jQuery.browser.msie ){ + try { + doc = (new DOMParser()).parseFromString( cadena, "text/xml" ); + if ( expresion ) { + alert( $( expresion, doc) ); + } + if (cadena == '') { + ajx_debug( 'XML.XMLdesdeTexto', 'No XML string for processing' ); + } else { + parseError = checkForParseError( doc ); + if (parseError.errorCode == 0) { + return doc; + } else { + ajx_debug ( 'XML.XMLdesdeTexto, processing xml', parserError.reason.concat( ', ').concat( parserError.srcText ) ); + doc = null; + } + } + + } catch( e ) { + if ( this._modo_debug ) { + objeto_debug.excepcion_parsing_xml = e; + objeto_debug.cadena_xml_fallo = cadena; + if ( jQuery.trim ( cadena ).length == 0 ) { + ajx_debug ( 'XML.XMLdesdeTexto', 'The xml document to be processed is empty' ); + } else { + parseError = checkForParseError(doc); + if (parseError.errorCode == 0) { + return doc; + } else { + ajx_debug ( 'XML.XMLdesdeTexto, processing xml (1)', parserError.reason.concat( ', ').concat( parserError.srcText ) ); + ajx_debug ( 'XML.XMLdesdeTexto, processing xml (2)', e ) + doc = null; + } + } + objeto_debug.cadena_xml_fallo = cadena; + } + } + + return doc; + + } else if ( jQuery.browser.msie ){ + doc = new ActiveXObject( "Microsoft.XMLDOM" ); + doc.loadXML( cadena ); + return doc; + } + }, //fin xmldesdetexto + + + + XSLdesdeTexto: function( cadena ){ + if ( !jQuery.browser.msie ) { + return this.XMLdesdeTexto( cadena ); + } + else if (jQuery.browser.msie){ + var doc = new ActiveXObject( "Msxml2.FreeThreadedDOMDocument.3.0" ); + doc.loadXML( cadena ); + return doc; + } + return null; + } + + }; + + function ajx_debug ( location, exception, message_type ) { + if ( message_type === undefined ) message_type = 'error'; + $ajx = jQuery ( '#ajx_debug' ) + if ( !( $ajx[0] === undefined ) ) { + var message = ( typeof exception == 'object' ) ? exception.toString() : exception; + $ajx.append( '

' ).concat( 'In ' ).concat( ''.concat( location ).concat( '' ) ).concat( ': ').concat( message ).concat ( '

') ); + } + } + + +})( jQuery ); diff --git a/test_module/cp.php b/test_module/cp.php new file mode 100644 index 0000000..9bd0d55 --- /dev/null +++ b/test_module/cp.php @@ -0,0 +1,152 @@ +$action( $parameters ); + + +class webservice { + function pre_xml ( $module, $webservice, $local_id_xsl ) { + $pre_xml = "\r\n"; + $pre_xml .= " \r\n"; + $pre_xml .= " \r\n"; + $pre_xml .= " \r\n"; + $pre_xml .= " \r\n\r\n"; + $in_xml .= " \r\n\r\n"; + $post_xml .= "\r\n"; + $post_xml .= ""; + + return $post_xml; + } +} + + +//This is a typical webservice. By using the framework, you would have here stuff to organize the webservices in +//directories, and functions to invoke them and so on... +class test_webservice extends webservice { + + + + public function test_action (&$p=null) { + global $client_cache_xsl_miss; + global $client_cache_xml_miss; + + global $module; + global $webservice; + global $action; + + //This is not the way for creating xml, only for testing purposes + + header ( 'Content-Type: text/xml' ); + + echo $this->pre_xml( $module, $webservice, "bands_1" ); + + if ( $client_cache_xsl_miss == '2' ) { + echo file_get_contents( 'test_response_xsl.xml' ); + } + + echo $this->in_xml( $module, $webservice, $action ); + + + if ( $client_cache_xml_miss >= '2' ) { + echo file_get_contents( 'test_response_xml.xml' ); + } + + echo $this->post_xml (); + + } + + + public function test_action_2 (&$p=null) { + global $client_cache_xsl_miss; + global $client_cache_xml_miss; + + global $module; + global $webservice; + global $action; + + //This is not the way for creating xml, only for testing purposes + + header ( 'Content-Type: text/xml' ); + + echo $this->pre_xml( $module, $webservice, "bands_2" ); + + if ( $client_cache_xsl_miss == '2' ) { + echo file_get_contents( 'test_response_xsl.xml' ); + } + + echo $this->in_xml( $module, $webservice, $action ); + + + if ( $client_cache_xml_miss >= '2' ) { + echo file_get_contents( 'test_response_xml_2.xml' ); + } + + echo $this->post_xml (); + } + + + +} + + +class test_webservice_2 extends webservice { + public function test_action_3 (&$p=null) { + global $client_cache_xsl_miss; + global $client_cache_xml_miss; + + global $module; + global $webservice; + global $action; + + //This is not the way for creating xml, only for testing purposes + + header ( 'Content-Type: text/xml' ); + + echo $this->pre_xml( $module, $webservice, "bands_3" ); + + if ( $client_cache_xsl_miss == '2' ) { + echo file_get_contents( 'test_response_xsl_2.xml' ); + } + + echo $this->in_xml( $module, $webservice, $action ); + + + if ( $client_cache_xml_miss >= '2' ) { + echo file_get_contents( 'test_response_xml.xml' ); + } + + echo $this->post_xml (); + } + + public function test_action_4 (&$p=null) { + header ( 'Content-Type: text/plain' ); + $miArray = array("manzana"=>"verde", "uva"=>"Morada", "fresa"=>"roja"); + echo json_encode($miArray); + } + +} + +?> \ No newline at end of file diff --git a/test_module/test_response_xml.xml b/test_module/test_response_xml.xml new file mode 100644 index 0000000..791faee --- /dev/null +++ b/test_module/test_response_xml.xml @@ -0,0 +1,25 @@ + + + Dream Theater + Riverside + Porcupine Tree + Opeth + Queensryche + Ephrat + Spock's Beard + Transatlantic + Tool + Blackfield + Therion + + + Metallica + Dream Theater + Iron Maiden + Pantera + Megadeth + Rage + Opeth + Therion + + \ No newline at end of file diff --git a/test_module/test_response_xml_2.xml b/test_module/test_response_xml_2.xml new file mode 100644 index 0000000..4743677 --- /dev/null +++ b/test_module/test_response_xml_2.xml @@ -0,0 +1,22 @@ + + + Porcupine Tree + Ephrat + Audioslave + Black Label Society + Green Day + Pearl Jam + Nirvana + Porcupine Tree + + + Joaquin Rodrigo + Beethoven + Ludvig Van Beethoven + Antonio Vivaldi + Wolfgang Amadeus Mozart + Paco de Lucia + Joaquin Turina + Manuel de Falla + + \ No newline at end of file diff --git a/test_module/test_response_xsl.xml b/test_module/test_response_xsl.xml new file mode 100644 index 0000000..ba1978a --- /dev/null +++ b/test_module/test_response_xsl.xml @@ -0,0 +1,52 @@ + + + +

List Of Bands

+ + + + +

Filter:

+
+ +
    + + + + + +
  • +
  • +
      + +
    +
  • +
    + +
    + + + + +
  • +
  • +
      + +
    +
  • +
    +
    +
    + +
+ +
+ + +
  • +
    + + +
  • +
    + \ No newline at end of file diff --git a/test_module/test_response_xsl_2.xml b/test_module/test_response_xsl_2.xml new file mode 100644 index 0000000..724fbef --- /dev/null +++ b/test_module/test_response_xsl_2.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/util.js b/util.js new file mode 100644 index 0000000..34f53fe --- /dev/null +++ b/util.js @@ -0,0 +1,17 @@ +function xml2Str(xmlNode) { + try { + // Gecko- and Webkit-based browsers (Firefox, Chrome), Opera. + return (new XMLSerializer()).serializeToString(xmlNode); + } + catch (e) { + try { + // Internet Explorer. + return xmlNode.xml; + } + catch (e) { + //Other browsers without XML Serializer + //alert('Xmlserializer not supported'); + } + } + return false; +} -- 2.45.2