miércoles, 23 de mayo de 2012

Aplicar una transformación xsl desde javascript cogiendo el archivo xml del ordenador del cliente.


Aunque podría poner una xsl  general en este ejemplo voy a utilizar la siguiente (por_un_clavo.xsl):

<?xml version="1.0"?>
     <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:template match="/">
          <xsl:apply-templates/>
     </xsl:template>
     <xsl:template match="por_un_clavo">
          <ul>
       <xsl:apply-templates/>
  </ul>
     </xsl:template>
     <xsl:template match="linea">
          <li>
       <xsl:value-of select="."/>
  </li>
     </xsl:template>
</xsl:stylesheet>

Para procesar, con ella, el xml siguiente (por_un_clavo.xml):

<?xml version="1.0" encoding="UTF-8"?>
<!-- <?xml-stylesheet type="text/xsl" href="por_un_clavo.xsl"?> -->
<por_un_clavo>
     <linea>Por un clavo se perdió una herradura,</linea>
     <linea>por una herradura, se perdió un caballo,</linea>
     <linea>por un caballo, se perdió una batalla,</linea>
     <linea>por una batalla, se perdió el Reino.</linea>
</por_un_clavo>

Si descomentamos la línea comentada podemos abrir el archivo xml con Internet Explorer y éste realizará la transformación directamente. Esto nos servirá para validar rápidamente nuestra xsl.

Si no queremos tener problemas con los acentos, las ñ y demás deberemos poner el encoding dentro del xml con el que realmente hayamos guardado nuestro archivo (trabajar con utf-8 es la mejor elección, olvidaros del ISO-8859-1 por muy latín que sea). Una forma de hacerlo, desde Windows, es escribiendo el xml en Word, guardando como texto y allí eligiendo la codificación (en Windows, por defecto y para variar, la codificación es propietaria de Microsoft y no es utf-8):


Una vez seleccionado el archivo de disco y transformado con nuestra xsl el resultado, con Firefox, será:


La página, con el código completo, se puede ver en:

El body de la página es, simplemente:

<input id="ficheroxml" type="file" name="ficheroxml" onchange="procesarXml();"/>
<div id="resultado"></div>

En él tenemos un input para seleccionar el archivo y un div que albergará el resultado de la transformación. En el momento en el que se selecciona el archivo se producirá el evento “onchange” y se llamará a la función javascript procesarXml().

Dentro del javascript hemos incluido la xsl como una variable de texto con todo su contenido:

     var xsl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> …

y hemos creado una instancia de un lector de ficheros:

     var reader = new FileReader();

Cuando se llama a la función procesarXml se ejecuta el siguiente código:

     if (document.getElementById("ficheroxml").files.length == 0) return;
     var fichero = document.getElementById("ficheroxml").files[0];
     reader.readAsText(fichero);

donde validamos si se ha seleccionado algún archivo, cogemos el primero de ellos y le pedimos al lector que lo lea como un archivo de texto.
Si se produce algún error se lanzará el evento onerror en el lector que definimos del modo siguiente:

     reader.onerror = function(event) {
           alert("Error leyendo el archivo, code: " + reader.error.code);
     }

Si todo va bien se lanzará el evento onload sobre el reader:

      reader.onload = function(event) {
           xml = event.target.result;
   parsearXml();
      }

Aquí guardaremos el resultado de la lectura en la variable xml y llamaremos a la función que realiza el parseo e introduce el resultado en el div "resultado":

function parsearXml() {
      var xsltProcessor = new XSLTProcessor();
      var parser = new DOMParser();
      xsltProcessor.importStylesheet(parser.parseFromString(xsl, "text/xml"));
      var resultDocument = xsltProcessor.transformToFragment(parser.parseFromString(xml, "text/xml"),                  
                                       document);
      document.getElementById("resultado").appendChild(resultDocument);
}

Para que esto funcione en Chrome (18.0.1025.162 m) es necesario arrancar la instancia de  Chrome con el switch “--allow-file-access-from-files” ya que, si no, no se nos permitirá, por razones de seguridad, acceder al archivo del  disco.

No hay comentarios:

Publicar un comentario