XSLT 2.0 es un interesante paso adelante en la tecnología de transformación XML, con ella, es posible crear productos de software que produzcan contenidos para diferentes dispositivos y plataformas. Con XSLT 2.0 y XPath 2.0, podemos realizar transformaciones de una forma mucho más sencilla y rauda haciendo uso de los XSLT Extension Objects.
Dicha la teoría (la cual a la hora de la hora no sirve para nada), me he topado con la necesidad en diversas ocasiones de hacer uso de las bondades antes mencionadas (entre otras que mencionaremos más adelante), lamentablemente con mis herramientas de desarrollo actual (VS.NET 2003, VS 2005 y VS 2008) no he podido echar mi imaginación a volar (Si estoy equivocado y si lo trae por favor corríjanme, yo en lo personal nunca he podido hacer XSLT 2.0), y es que ante problemas “piñatas” siempre son necesarias soluciones “piñatas” que requieren opciones que se salen un poquito fuera de lo ordinario. Espero en las próxima versiones de estas herramientas (VS 2010), venga ya considerado este estándar (desconozco si en el CTP hasta el día del POST esté ya considerado).
De cualquier forma, hay una opción de nuestros amigos de Altova (http://www.altova.com/altovaxml.html) llamada AltovaXML, muy versátil para realizar este tipo de transformaciones, ya que es un poderoso:
- Motor de validación XML
- Motor XSLT 1.0
- Motor XSLT 2.0
- Motor XQuery 1.0
- Motor de validación XBRL
Con los cuales podemos realizar todo tipo de operaciones soportadas por el estándar W3C (para aplicaciones COM, Java y .NET), con todo el vigor de Altova, ah, y también: ¡GRATIS!
Pero bueno, ¿Cómo diantres lo usamos?, muy sencillo, solamente hay descargar la herramienta de: http://www.altova.com/altovaxml.html, isntalarla y agregar dentro de nuestro proyecto la referencia al assembly Altova.AltovaXML.dll (C:\Archivos de programa\Microsoft.NET\Primary Interop Assemblies\Altova.AltovaXML.dll por default). Si nos marca cosas extrañas, hay que procurar registrar el componente (AltovaXML_COM.exe /regserver)
Ya una vez realizado esto, creamos nuestra transformación XLST 2.0:
|
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:barreteros_funct="http://www.barreteros.net"> <xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template name="example" match="/"> <xsl:value-of select="barreteros_funct:index-of-string('Sergio', 'gio')"/> </xsl:template> <xsl:function name="barreteros_funct:index-of-string"> <xsl:param name="arg"/> <xsl:param name="substring"/> <xsl:sequence select=" if (contains($arg, $substring)) then (string-length(substring-before($arg, $substring))+1, for $other in barreteros_funct:index-of-string(substring-after($arg, $substring), $substring) return $other + string-length(substring-before($arg, $substring)) + string-length($substring)) else () "/> </xsl:function>
</xsl:stylesheet>
|
Aquí estamos creando una función (y recursiva apa!) llamada barreteros_funct:index-of-string, la cual no da el index-of de una cadena contenida en otra, recibe dos parámetros como podemos ver: arg, que es la cadena original y substring que es la cadena que deseamos saber el index).
Esta función, se manda llamar directamente desde el atributo select desde cualquier función xsl, como si se tratase de una función propia del estándar:
<xsl:value-of select="barreteros_funct:index-of-string('Sergio', 'gio')"/>
Esta nos arrojará como resultado un 4: 'Sergio', obvio.
OJO: Si esta transformación la abrimos desde nuestro IDE de desarrollo comentado anteriormente, nos va a pintar un… grandioso mensaje de error a nivel <xsl:function subrayando la palabra de color azul (como si fuera una falta horrografía en Word). Pero no os preocupéis, si este error les causa problemas, cierren el archivo, así ya no lo verán. Ahora procederemos a realizar la transformación mediante AltovaXML:
|
Protected Sub TransformarAltova(ByVal xslPath As String, ByVal strXML As String, ByVal TransformPath As String)
Dim xslt2 As Altova.AltovaXML.IXSLT2 = New Altova.AltovaXML.Application().XSLT2() xslt2.InputXMLFromText = strXML xslt2.XSLFileName = xslPath xslt2.Execute(TransformPath) End Sub Protected Function TransformarAltova(ByVal xslPath As String, ByVal strXML As String) As String Dim xslt2 As Altova.AltovaXML.IXSLT2 = New Altova.AltovaXML.Application().XSLT2() xslt2.InputXMLFromText = strXML xslt2.XSLFileName = xslPath Return xslt2.ExecuteAndGetResultAsString End Function |
Aquí hay dos funciones polimórficas, la primera realiza la transformación en una ruta determinada (TransformPath), la segunda regresa el resultado de la transformación en un arreglo de caracteres (As String). Simplemente se instancia el XSLT2 parser y llamamos el método Execute o ExecuteAndGetResultAsString según el escenario deseado.
De esta forma estamos solventando el problema REAL.
OJO: dada nuestra transformación mediante AltovaXML, necesitamos liberar el COM object de Altova:
System.Runtime.InteropServices.Marshal.ReleaseComObject(XSLT2)
Si no realizamos esto, el proceso de Altova se queda corriendo dentro de los proceso de la maquina ejecutante y no se apaga o finaliza hasta que no se cierra la aplicación que lo manda ejecutar.
En nuestra próxima entrega veremos: ¿QUÉ TAN CHONCHO PUEDE SER UN XML PARA QUE LO PROCESE LINQ SIN PROBLEMAS?