¿Qué tan funcional es XSLT?

Bryan Valencia Suárez
Bancolombia Tech
Published in
21 min readMar 23, 2021

En la actualidad, existen numerosos lenguajes basados en la programación funcional o que incluyen elementos de este paradigma, pero que no podrían ser denominados lenguajes de programación funcionales puros y, generalmente, desde el punto de vista de paradigmas de programación, se les otorga el nombre de lenguajes híbridos.

En algunas ocasiones y dependiendo de la funcionalidad del lenguaje, no cumplir estrictamente con las características de la programación funcional favorece el proceso de desarrollo de software. Por mencionar algunos, puede decirse que Scala, Lisp, Shema y Ocaml son ejemplos de lenguajes híbridos que no son tan dogmáticos ya que aceptan elementos de los lenguajes imperativos.

Esta mezcla de conceptos de diferentes paradigmas puede ser desafiante al momento de empezar a codificar con uno de estos lenguajes, sobre todo cuando el desarrollador ha tenido fuerte experiencia en un paradigma no funcional, situación que es bastante común. Un ejemplo específico de esto dentro de Bancolombia es la utilización del lenguaje XSLT, como parte del desarrollo de varios de los componentes de la capa de integración.

XSLT es un lenguaje con una sintaxis compuesta exclusivamente de plantillas XML y con una fuerte base en programación funcional. En el caso de Bancolombia, XSLT es utilizado en la implementación de servicios en IBM WebSphere DataPower. En esta plataforma se aprovecha la funcionalidad principal de este lenguaje para el tratamiento y transformación de mensajería XML, pero el uso correcto de XSLT depende, en gran medida, de la comprensión de sus bases en la programación funcional y sus singularidades. Tener claridad en estos puntos no solo facilita el encuentro inicial con este lenguaje, sino que además posibilita la generación de un código más eficiente.

Para favorecer el entendimiento y, por ende, el uso adecuado de este lenguaje, a continuación se realiza una revisión de XSLT desde el punto de vista de paradigmas de programación, específicamente desde el funcional. El objetivo es, entonces, definirlo, describirlo e intentar verificar, mediante pruebas en código, el cumplimiento de cinco de las características de la programación funcional.

1. Transformaciones XSL (XSLT)

XSLT (Extensible Stylesheet Language Transformations) es un lenguaje de programación diseñado para transformar documentos basados en etiquetas (XML, HTML, etc.) en otros documentos de este mismo tipo. En otras palabras, con este lenguaje puede generarse un nuevo documento mediante la conversión de un documento de entrada, comúnmente archivos XML [1].

La organización a cargo de la estandarización de este lenguaje es el consorcio W3C. En su última recomendación, publicada en junio del 2017 [2], se menciona que XSLT está diseñado principalmente para conversiones de archivos XML. Aunque esto último es cierto, XSLT está siendo utilizado para generar otro tipo de documentos como HTML e incluso otros formatos basados en textos [3].

Esta funcionalidad tan específica hace de XSLT un lenguaje con una orientación y características también particulares, una de ellas es que se codifica usando la sintaxis de XML. Cada archivo generado es llamado stylesheet (hoja de estilo). Una hoja de estilo debe ser un archivo XML bien formado, esto quiere decir que respeta las recomendaciones publicadas por W3C para XML [1].

Una hoja de estilo describe reglas para transformar datos de entrada en datos de salida. Estos datos deben ser instancias de XDM (XQuery and XPath Data Model) [4] que permiten modelar cada componente (nodo, atributo, árbol, etc.) dentro de una transformación XSLT. Generalmente, estos datos son partes de un documento XML a las que se les denomina árboles.

Ejemplo de hoja de estilo:

1.1. XPath

XPath (XML Path Language) es un lenguaje que nació con el objetivo de permitir la navegabilidad entre los nodos de un árbol de un documento XML. La importancia de este lenguaje radica en su potencial aplicación como un lenguaje para consultas en XML [5]. Es un estándar también mantenido por la organización W3C en una recomendación separada, esto con el fin de permitir que el lenguaje pueda ser usado en otros contextos.

XPath es básicamente un lenguaje tipo query, capaz de seleccionar nodos mediante la navegación del árbol en cualquier dirección y aplicar predicados basados en el valor y la posición del nodo. Esto también incluye facilidades para la manipulación básica de strings, computación numérica y algebra booleana. Por ejemplo, la expresión XPath ../@titulo selecciona el atributo título del elemento que es el padre del nodo actual [6].

LLas expresiones XPath son usadas para seleccionar nodos de entrada para procesamiento, testear condiciones y calcular valores para la inserción dentro del árbol de salida.

Una forma simple de una expresión XPath es el patrón, usado en las reglas de plantilla para definir a cuáles nodos se les aplicará cierto conjunto de reglas.

1.2. Un sistema de dos lenguajes: XSLT y XPath

XPath es un sublenguaje embebido en XSLT. Cada navegación que se deba llevar a cabo en el documento XML de entrada, debe realizarse usando la sintaxis de XPath en las correspondientes estructuras destinadas para este fin por XSLT, por lo tanto, XSLT sin XPath no podría ser utilizado para alguna tarea de transformación.

El hecho de que XPath haya sido diseñado para ser un lenguaje embebido en otro lenguaje tiene algunas consecuencias, entre estas las siguientes mencionadas por Kay [3]:

1. Un lenguaje embebido no necesita ser computacionalmente completo, esto hace que XPath pueda:

· Acceder a las variables, pero no declararlas

· Llamar funciones, pero no definirlas

· Navegar en los nodos de un árbol, pero no crear nuevos nodos

Como puede deducirse, aunque XPath le ofrece a XSLT varias funcionalidades, especialmente la navegación en los árboles XML. Solo con XSLT se pueden definir funciones, declarar variables y crear nodos de árbol.

2. Como lenguaje embebido, XPath depende del contexto establecido por el lenguaje que lo alberga. Si una forma de comunicación embebida debe estar bien integrado con la que lo alberga, entonces deben compartir información para que el usuario no tenga que declarar cosas dos veces, una para cada una. La información que XPath comparte con XSLT se llama contexto.

Esto es que una variable creada con XSLT puede ser utilizada directamente por XPath, como si previamente hubiera sido creada en los dos lenguajes.

3. Un lenguaje embebido puede ser llamado por el lenguaje que lo alberga, pero no viceversa. XSLT puede invocar XPath, pero XPath no puede invocar XSLT. Esto significa que hay una capacidad de compilación incompleta de las expresiones cuando el lenguaje XSLT se considera como un todo. Sin embargo, XPath puede invocar XSLT indirectamente por medio de llamadas a funciones.

Distinción entre XPath y XSLT en una hoja de estilo (en azul XPath, en verde XSLT):

En el código mostrado, se resaltan en azul aquellos componentes de la hoja de estilo que son parte de XPath, el resto del documento (en verde) son XSLT.

Para la versión 3.0 de XSLT, como una opción de implementación, también se puede usar XPath 3.1, de esta manera, algunas características que están únicamente disponibles en la versión 3.1 de XPath como generadores de números aleatorios, funciones para ordenar, entre otras, podrían incluirse y utilizarse [2].

1.3. Procesador XSLT

El procesador XSLT es el software responsable de transformar los árboles de entrada en árboles de salida usando una hoja de estilo XSLT [2]. El procesador toma uno o más documentos fuente, junto con una o más hojas de estilo XSLT, y los procesa para producir un documento de salida.

El paradigma básico de procesamiento es la coincidencia de patrones. En lugar de listar una secuencia imperativa de acciones para desarrollar en un entorno de estado, las reglas de plantilla solo definen cómo manejar un nodo coincidente con un patrón particular de XPath [6].

Generalmente, la estructura de árbol de entrada se produce a partir del análisis de un documento XML, y la estructura del árbol se serializará en otro documento XML. A pesar de esto, el procesador XSLT manipula estructuras de árbol, no secuencias de caracteres XML. Esto significa que las distinciones en el documento de origen que son irrelevantes para la estructura de árbol no son accesibles para el procesador XSLT. Por ejemplo, no es posible aplicar un procesamiento diferente dependiendo de si los atributos están entre comillas simples o comillas dobles, ya que se consideran representaciones diferentes del mismo documento subyacente. Más sutilmente, significa que procesar un elemento de entrada, o generar un elemento de salida, es una operación atómica [6].

Figura 1. Arquitectura del procesador XSLT Saxon [13]

2. ¿Qué tipo de lenguaje es XSLT desde el punto de vista de paradigmas de programación?

En 2005, Michael Kay [6] mencionó que, aunque XSLT se basa en ideas de programación funcional, todavía no era un lenguaje de programación completamente funcional, ya que carecía de la capacidad de tratar las funciones como un tipo de datos de primera clase.

La idea de un programa funcional es describir el resultado como una función de la entrada. XSLT es un lenguaje de transformación; está diseñado para transformar un documento de entrada en uno de salida. Entonces, podemos considerar una hoja de estilo como una función que define esta transformación: una hoja de estilos es una función O = S (I) donde I es el documento de entrada, S es la hoja de estilos y O es el documento de salida.

En esencia, XSLT nace como un lenguaje basado en los conceptos y principios de la programación funcional. Esto se debe a que una hoja de estilo está compuesta de plantillas que son esencialmente funciones puras: cada una define un fragmento del árbol de salida como una función de un fragmento del árbol de entrada y no produce efectos de lado. Por lo anterior, puede decirse desde el punto de vista de paradigmas de programación, que este es un lenguaje declarativo, ya que en XSLT estas funciones no están organizadas en ningún orden en particular, no tienen que coincidir con el orden de la entrada o el orden del resultado, y de hecho hay muy pocas pistas sobre qué orden o anidación de elementos espera el autor de la hoja de estilo encontrar en el documento fuente. En XSLT se especifica qué salida se debe generar cuando se producen patrones particulares en la entrada, a diferencia de un programa de procedimiento en el que debe decir qué tareas realizar y en qué orden [3].

Otro elemento importante desde este punto de vista es que XSLT es un lenguaje compuesto por funciones. Las que son en XSLT toman varias formas. Las explícitas en XSLT 2.0 son aquellas que se codifican usando un elemento <xsl:function>. Sin embargo, las plantillas (tanto plantillas con nombre como reglas de plantilla) también actúan como funciones: la única diferencia real entre una <xsl:function> y una <xsl:template> es que la primera se llama desde una expresión XPath, y la última desde una instrucción. El siguiente código muestra la estructura de estos dos componentes.

En la recomendación publicada por el consorcio W3C [2] para la versión 3.0 de este lenguaje en el año 2017, se menciona que las funciones ahora son valores de primera clase, y se pueden pasar como argumentos a otras funciones (de orden superior), haciendo que XSLT sea un lenguaje de programación funcional completamente desarrollado.

Aunque la W3C catalogue este lenguaje como uno de programación funcional completamente desarrollado, en la siguiente sección se revisarán individualmente 5 características de la programación funcional en XSLT para comprobar su cumplimiento y encontrar condiciones de este lenguaje, relacionadas con los conceptos de este paradigma de programación.

2.1. Análisis de características de la programación funcional en XSLT

En este apartado, se realiza una revisión de las siguientes cinco características de la programación funcional en el lenguaje XSLT:

1. Concepto de estado

2. Transparencia referencial

3. Polimorfismo paramétrico

4. Evaluación perezosa

5. Funciones de orden superior

Para esto, se hace un acercamiento teórico de lo que cada concepto significa, se toman algunos apuntes de la documentación oficial del lenguaje, y se muestra el código de las hojas de estilo codificadas para realizar pruebas que permitieran evidenciar el cumplimiento de cada una de estas características en XSLT.

Para el desarrollo de estas pruebas se ha utilizado el procesador XSLT RaptorXML Sever 2018 [14], que es un producto de la empresa ALTOVA. Se eligió este en particular porque soporta las 3 versiones de XSLT: 1.0, 2.0 y 3.0, factor importante para las pruebas que se describen a continuación.

2.1.1. Concepto de estado

El estado de la aplicación es la memoria almacenada para la aplicación, que puede ser en forma de variables, propiedades, etc. Los lenguajes declarativos se caracterizan por no tener un estado implícito y, por lo tanto, el énfasis se pone completamente en la programación con expresiones (o términos) posibilitando el diseño de software sin estado [15].

La ausencia de estado hace que la creación de iteraciones o bucles en los lenguajes funcionales deba llevarse a cabo a través de recursión, ya que no es posible contar con variables que puedan mutar su valor para indicar la posición de la iteración y una función de corte.

En la especificación de XSLT, se menciona que las iteraciones en este lenguaje deben llevarse a cabo con recursión, como se haría en un lenguaje funcional, pero la realidad es que en XSLT existen ciclos como “for-each” e “iterate”, que hacen que para el desarrollador no sea necesario el uso de recursión. La sola existencia de estas estructuras de control podría considerarse como una muestra del no cumplimiento riguroso de esta característica de la programación funcional, pero la realidad es que internamente el lenguaje transforma esas definiciones en estrategias recursivas que son transparentes a ojos del desarrollador.

Por otra parte, la ausencia de estado en XSLT teóricamente se respeta, ya que, aunque en este lenguaje sí existe el concepto de variable, no existen las instrucciones de asignación. Las variables pueden ser mejor descritas como “constantes” ya que pueden iniciarse, pero nunca cambian su valor, es decir, son inmutables. La razón es que toda la manipulación que se necesita hacer se divide en una serie de funciones que toman un árbol (o valor) y devuelven otro árbol.

Para ir un poco más allá con la evaluación de esta característica en XSLT, se ha codificado la hoja de estilo que se presenta a continuación. En ella hay una plantilla en la que se ha iniciado una variable con nombre “numero” dos veces. En la primera, a la variable se le asigna el valor “5”, y en la segunda creación, se inicia con el valor de la primera variable creada y se suma el número 9. La plantilla se ha ejecutado dos veces, con versiones de procesadores diferentes.

En la ejecución de la anterior hoja de estilo con el procesador XSLT 1.0, se genera el siguiente error:

17:36:55,123 ERROR [main] JAXPSAXProcessorInvoker  - file:/C:/Users/bryan/workspace/project_xsl/WebContent/File.xsl: line 8: Se ha definido varias veces la variable 'numero' en el mismo ámbito.javax.xml.transform.TransformerConfigurationException: file:/C:/Users/bryan/workspace/project_xsl/WebContent/File.xsl: line 8: Se ha definido varias veces la variable 'numero' en el mismo ámbito.

Un error muy similar se obtendría en lenguajes puramente funcionales como Haskell e incluso en uno imperativo, pero si se detalla esto desde la programación funcional, dos variables no deberían ser iniciadas con el mismo nombre porque esto representaría una mutación.

Cuando se ejecuta la misma hoja de estilo con un procesador XSLT 3.0 se genera el siguiente resultado:

<?xml version="1.0" encoding="UTF-8"?>14

Siendo estrictos con las definiciones, este es un resultado que NO concordaría con el paradigma funcional, ya que, aunque este lenguaje no contiene estructuras de asignación, es decir, no hay una forma explícita para cambiar el valor de una variable, la realización de una doble inicialización podría entenderse como una mutación. Esto se evidenció ya que el programa sumó el valor de la variable anterior “5” con “9” y generó un documento XML de salida con el número “14”.

Claro que en este punto también es valioso mencionar que en XSLT existen ámbitos que impiden la reasignación de variables fuera de ellos, lo que significa que el inicio de la variable en un ámbito X con el mismo nombre de una existente en el ámbito Y, no representaría realmente una mutación porque los valores dados a la variable en un ámbito no afectarían los valores trabajados en otro. Pero, se reitera que, siendo dogmáticos con el cumplimiento de la programación funcional, en un mismo ámbito esta “reiniciación” no debería ser posible.

Aquí es importante resaltar que, como se evidenció, el procesador juega un papel importante en cuanto al cumplimiento de la característica de la ausencia de estado en XSLT, ya que de la implementación de este y de la versión del lenguaje depende la restricción de estructuras como la que se presenta en el ejemplo anterior.

2.1.2. Transparencia referencial

En programación funcional, la transparencia referencial es un término que se refiere a la propiedad por la cual, en un programa, iguales pueden ser reemplazados por iguales [15]. En otras palabras, el resultado de evaluar una expresión compuesta depende únicamente del resultado de evaluar las subexpresiones que la componen y de nada más; no depende de la historia del programa en ejecución ni del orden de evaluación de las subexpresiones que la componen. Para lograr esto, el lenguaje debe estar libre de efectos de lado y producir siempre la misma salida para la misma entrada dada.

En XSLT las reglas de plantilla y las funciones explícitas actúan como funciones independientes relacionando una pieza de salida a una pieza de entrada. Las funciones y plantillas en XSLT no tienen efectos de lado; su salida es una función pura de su entrada. Las funciones explícitas siguen este modelo más estrictamente que las plantillas. Las plantillas son menos puras porque también toman la posición actual en el documento de entrada y otra información de contexto como parámetros de entrada implícitos [3].

Debido a que XSLT está compuesto de funciones puras, estas pueden llamarse cualquier cantidad de veces, en cualquier orden, y producirán el mismo resultado cada vez. Para intentar evidenciar la característica de transparencia referencial en este lenguaje de programación se plantea la siguiente prueba:

Consiste en utilizar un documento XML de entrada, y usar de manera independiente dos hojas de estilo con las mismas funciones cada una, pero en un orden diferente.

Documento de entrada:

Primera hoja de estilo:

Resultado primera hoja de estilo:

<?xml version="1.0" encoding="UTF-8"?>
<cuadradoEncontrado/>
<trianguloEncontrado/>
<circuloEncontrado/>

Segunda hoja de estilo:

Resultado segunda hoja de estilo:

<?xml version="1.0" encoding="UTF-8"?>
<cuadradoEncontrado/>
<trianguloEncontrado/>
<circuloEncontrado/>

Nótese en las secciones de código previas, que tanto la primera como la segunda hoja de estilo contienen las plantillas con los valores de match para “triangulo”, “circulo” y “cuadrado”, pero estas están especificadas en un orden diferente.

Lo que podría suponerse inicialmente es que el orden de estas plantillas (diseñadas para el hallazgo de esos elementos en el XML de entrada) afectaría el documento de salida generado, es decir, el orden en la indicación del hallazgo de cada figura sería diferente para cada prueba, pero el resultado obtenido al ejecutar las dos hojas de estilo fue exactamente el mismo.

Lo anterior puede considerarse como una indicación de que en XSLT hay transparencia referencial, ya que el orden de la ejecución de las funciones NO altera el resultado de la transformación. El resultado en este caso solo podría afectarse si se cambiara el documento XML de entrada.

2.1.3. Polimorfismo paramétrico

El polimorfismo paramétrico se usa para distinguirlo de otro tipo que se denomina ad hoc o de sobrecarga. Los dos se pueden distinguir de la siguiente manera: a una función con polimorfismo paramétrico no le importa de qué tipo son sus argumentos y, por lo tanto, se comporta de forma idéntica independientemente de estos. Por el contrario, una función con polimorfismo ad hoc sí se preocupa y, de hecho, puede comportarse de manera diferente para diferentes tipos. Dicho de otra manera, el polimorfismo ad hoc es realmente solo un dispositivo sintáctico para sobrecargar un nombre o símbolo de función en particular con más de un significado [15].

Nótese en la siguiente hoja de estilo que se ha creado una función llamada “bancolombia:fPolimorfica”, que recibe dos parámetros sin indicar su tipo de dato. También se realiza un llamado a la función pasando como primer parámetro un string y como segundo, un valor decimal.

Hoja de estilo con función sin indicación de tipo de dato en parámetros:

El archivo de salida generado de la ejecución de la anterior hoja de estilo es el siguiente, donde puede evidenciarse que se ha ejecutado correctamente la función.

<?xml version="1.0" encoding="UTF-8"?>
<salida>cadena 5</salida>

Se realizó un segundo llamado a la función donde se especifican los parámetros en el orden contrario, como se muestra en el siguiente código:

<xsl:copy-of select=”bancolombia:fPolimorfica($atributoDecimal, $atributoString)” />

También se obtuvo un archivo de salida que evidencia la ejecución correcta de la función.

<?xml version="1.0" encoding="UTF-8"?>
<salida>5 cadena</salida>

Con este ejercicio se comprueba que en XSLT la propiedad de polimorfismo paramétrico se cumple, ya que la función pudo ser procesada sin tener como restricción el tipo de datos de sus parámetros.

En XSLT la indicación del tipo de parámetro en las funciones es opcional. En la siguiente hoja de estilo se presenta la misma función, pero el primer parámetro se indica como decimal y el segundo, como string. Además de eso se hace un llamado a la función pasando como primer parámetro un string y como segundo, un valor decimal.

Al ejecutar la anterior hoja de estilo se obtiene el siguiente mensaje de error:

Error: file:///C:/Users/bryan/workspace/project_xsl/WebContent/polimorfismoParametrico/stylesheet.xsl:10: El tipo de elemento no se puede equiparar con el tipo necesarioDetalles:
XPTY0004: El tipo de elemento necesario es xs:decimal, pero se suministró el tipo xs:string

Como última prueba en esta característica de la programación funcional, se han intentado crear dos funciones con el mismo nombre, pero diferente grupo de parámetros para comprobar el soporte de XSLT de polimorfismo de sobrecarga.

Como puede notarse en el siguiente mensaje de error, en XSLT el polimorfismo de sobrecarga no está soportado, lo que va de la mano con las características de la programación funcional.

Error: file:///C:/Users/bryan/workspace/project_xsl/WebContent/polimorfismoParametrico/stylesheet.xsl:18: La función 'bancolombia:fPolimorfica' está repetidaDetalles:
XTSE0770: Una hoja de estilos no puede contener dos o más funciones con el mismo expanded-QName, la misma aridad y la misma prioridad de importación. A no ser que haya otra función con el mismo expanded-QName y la misma aridad y una mayor prioridad de importación

2.1.4. Evaluación perezosa

En la teoría del lenguaje de programación, la evaluación perezosa o llamada por necesidad es una estrategia de evaluación que retrasa el cálculo de una expresión hasta que se necesita su valor. En XSLT esto proporciona dos beneficios [3]:

1. Evita asignar memoria para contener los resultados. (Aunque las máquinas modernas tienen grandes cantidades, procesar grandes documentos XSLT puede requerir mucha memoria, y la sobrecarga de asignar y desasignar de forma dinámica representa una gran parte del costo del procesamiento XSLT).

2. La evaluación lenta a veces significa que una expresión no necesita ser evaluada en absoluto. Para tomar un ejemplo simple, en una llamada a función tal como «string-join ($sequence, $separator)», no hay necesidad de evaluar el segundo argumento, a menos que el primerosea una secuencia que contenga dos o más elementos.

Como se verá en los ejercicios siguientes, la evaluación perezosa en XSLT depende, en gran medida, del procesador elegido, ya que en tiempo de compilación podría hacer evaluaciones incluso cuando los parámetros o las variables nunca se usan dentro del programa [16].

En la prueba que puede verse en la siguiente hoja de estilo, se crea una función “bancolombia:fLazy”, que recibe dos parámetros pero que no hace uso del segundo de ellos. Nótese que al momento de llamar la función se envía una cadena y una indicación de dividir 4 entre 0 (“4 div 0”).

También se ha creado una plantilla con la misma estructura que la función anterior para evaluar si el comportamiento es el mismo en todos los tipos de funciones que XSLT ofrece. Note que en la plantilla el atributo 2 tampoco es usado.

La ejecución de cualquiera de estas hojas de estilo genera el siguiente mensaje de error:

Error: file:///C:/Users/bryan/workspace/project_xsl/WebContent/lazyEvaluation/stylesheet.xsl:15: División por cero
Detalles:
FOAR0001: División por cero

Esto significa que se está evaluando el argumento “4 div 0”, aunque no está siendo usado por la función “bancolombia:fLazy” ni por la plantilla “tempLazy”. Como se ha explicado previamente, esto se debe a que el procesador, en tiempo de compilación, hace las operaciones que estén a su alcance, y como la expresión “4 div 0” no contiene variables, está en la capacidad de validar que es un error, incluso si el atributo no se utiliza.

Como complemento a esta prueba, también se ha llevado a cabo un ejercicio en el que el compilador no puede evaluar una división por cero ya que el divisor está en el atributo “y” de la tercera figura del documento de entrada, y en tiempo de compilación este valor no puede ser obtenido.

Archivo de entrada:

Hoja de estilo:

Archivo de salida:

<?xml version="1.0" encoding="UTF-8"?>
<salida>XXX</salida>

En este caso, podría decirse que hubo evaluación perezosa: el procesador nunca generó un error por la división por cero, debido a que esta nunca fue evaluada ya que la función nunca utilizó el segundo atributo.

Lo anterior permite concluir que la evaluación perezosa en XSLT está limitada por cálculos que pueden llevarse a cabo en tiempo de compilación y que dependen de la implementación del procesador.

2.1.5. Funciones de orden superior

Se dice que una función es de orden superior cuando puede tomar funciones como parámetros y/o devolver otras como resultado. Ésta era la única característica de la programación funcional que, según la documentación, XSLT no tenía hasta junio del año 2017, cuando W3C lanzó la versión 3.0 de este lenguaje y con ella el soporte de funciones de orden superior.

El hecho de que solo a partir de la versión 3.0 de XSLT se soporten las funciones de orden superior, significa que también hay una limitante en cuanto a los procesadores. Si un programador desea usar la versión 3.0 de este lenguaje, debe utilizar un procesador que la soporte.

En caso de que se tengan dudas sobre el soporte de funciones de orden superior del procesador que se está usando, se puede ejecutar una línea de código como esta xsl:supports-higher-order-functions que retorna “yes” o “no”, según corresponda.

En el siguiente ejemplo, puede verse la utilización de la nueva capacidad de XSLT 3 para el manejo de funciones de orden superior. Nótese en la hoja de estilos que se han creado 3 funciones: “bancolombia:area”, “bacolombia:perimetro” y “bancolombia:calcularrec”; la última es una función de orden superior, que admite como parámetro otra función. Esto puede evidenciarse en el cuerpo de la estructura for-each, ya que se está llamando la función “bancolombia:calcularrec”, pero se está especificando en dos momentos como último parámetro las funciones “bancolombia:area” y “bancolombia:perimetro”, respectivamente.

El objetivo de esta prueba es obtener el área y perímetro de cada figura sin llamar explícitamente las funciones que permiten calcular estos valores, en lugar de eso se llama una función y se envía como parámetro la respectiva para el cálculo correspondiente.

Archivo de entrada:

Hoja de estilo

Documento de salida:

En el documento de salida se evidencia la correcta ejecución de las funciones para cada uno de los dos elementos “figura” del documento XML de entrada.

Conclusiones

Puede mencionarse como conclusión de la revisión realizada que hay variaciones significativas entre las versiones XSLT, respecto al cumplimiento de las condiciones para que pueda considerarse un lenguaje funcional. El manejo de funciones de orden superior, por ejemplo, solo está disponible a partir de la versión 3.0.

De igual forma, el cumplimiento de las características de la programación funcional en XSLT está sujeto al procesador que compila e interpreta las hojas de estilos. Ejemplo de esto es el caso de la evaluación perezosa y el manejo de estado para las variables, que dependen de la implementación del procesador utilizado.

Por lo anterior, XSLT puede considerarse un lenguaje de programación que cumple características de la programación funcional, pero que no es puramente funcional. Esto se debe, entre otros elementos vistos, a la evaluación perezosa dependiente del procesador y a la existencia de ciclos como “for-each” e “iterate”, que de alguna manera dejan como opcional la recursión desde el punto de vista del programador, y que, siendo dogmáticos con los conceptos, van en contra de las bases de la programación funcional.

Con relación a lo mencionado por la W3C, acerca de que XSLT desde su versión 3 puede ser considerado como un lenguaje de programación completamente desarrollado, debe tenerse en cuenta que esto no es lo mismo que decir que XSLT es puramente funcional, por lo que las conclusiones generadas en esta revisión no van en contra de lo dicho por este consorcio, ya que el hecho de que este lenguaje tenga todas las capacidades de un lenguaje de programación funcional, NO significa que no adicione algunos conceptos de la programación iterativa.

Esta exploración de las capacidades de XSTL, en combinación con la exposición y ejemplificación de varios de los conceptos del paradigma funcional, puede ser un buen primer acercamiento para descifrar la razón de muchas de sus particularidades y servir para entender y mejorar las implementaciones realizadas en el área de integración del banco en herramientas como Datapower, en la que se tiene un uso bastante amplio de XSLT.

Referencias

[1] T. Bray, J. Paoli, C. M. Sperberg-McQueen, E. Maler y F. Yergeau, «Extensible Markup Language (XML) 1.0,» 2008. [En línea]. Available: https://www.w3.org/TR/xml/. [Último acceso: 28 Octubre 2017].

[2] M. Kay, «XSL Transformations (XSLT) Version 3.0,» 8 Junio 2017. [En línea]. Available: https://www.w3.org/TR/xslt-30/. [Último acceso: 28 Octubre 2017].

[3] M. Kay, XSLT 2.0 and XPath 2.0 Programmer’s Reference, Cuarta ed., Indianapolis, Indiana: Wiley Publishing, 2008.

[4] N. Walsh, A. Berglund y J. Snelson, «XQuery and XPath Data Model 3.0,» 8 Abril 2014. [En línea]. Available: https://www.w3.org/TR/xpath-datamodel-30/. [Último acceso: 28 Octubre 2017].

[5] G. Gottlob, C. Koch y R. Pichler, «Efficient algorithms for processing XPath queries,» ACM Transactions on Database Systems, vol. XXX, nº 2, pp. 444–491, 2005.

[6] M. Kay, «What kind of language is XSLT?,» 20 Abril 2005. [En línea]. Available: https://www.ibm.com/developerworks/library/x-xslt/. [Último acceso: 9 Diciembre 2017].

[7] J. Clark, «XSL Transformations (XSLT) Version 1.0,» 16 Noviembre 1999. [En línea]. Available: https://www.w3.org/TR/1999/REC-xslt-19991116. [Último acceso: 9 Diciembre 2017].

[8] J. Clark y S. DeRose, «XML Path Language (XPath) Version 1.0,» 16 Noviembre 1999. [En línea]. Available: https://www.w3.org/TR/xpath/. [Último acceso: 9 Diciembre 2017].

[9] M. Key, «XSL Transformations (XSLT) Version 2.0,» 23 Enero 2007. [En línea]. Available: https://www.w3.org/TR/2007/REC-xslt20-20070123/. [Último acceso: 9 Diciembre 2017].

[10] A. Berglund, S. Boag, D. Chamberlin, M. F. Fernández, M. Kay, J. Robie y J. Siméon, «XML Path Language (XPath) 2.0 (Second Edition),» [En línea]. Available: https://www.w3.org/TR/xpath20/. [Último acceso: 9 Diciembre 2017].

[11] J. Robie, D. Chamberlin, M. Dyck y J. Snelson, «XML Path Language (XPath) 3.0,» 8 Abril 2017. [En línea]. Available: https://www.w3.org/TR/xpath-30/. [Último acceso: 9 Diciembre 2017].

[12] J. Robie, M. Dyck y J. Spiegel, «XML Path Language (XPath) 3.1,» 21 Marzo 2017. [En línea]. Available: https://www.w3.org/TR/xpath-31/. [Último acceso: 9 Diciembre 2017].

[13] M. Kay, «Saxon: Anatomy of an XSLT processor,» 20 Abril 2005. [En línea]. Available: https://www.ibm.com/developerworks/library/x-xslt2/. [Último acceso: 13 Enero 2018].

[14] ALTOVA, «RaptorXML Server,» 2017. [En línea]. Available: https://www.altova.com/es/raptorxml. [Último acceso: 15 Enero 2018].

[15] P. Hudak, «Conception, evolution, and application of functional programming languages,» ACM Computing Surveys (CSUR), vol. 21, nº 3, pp. 359–411, 1989.

[16] M. Kay, «XSLT 2.0 and lazy evaluation,» 3 December 2006. [En línea]. Available: https://www.oxygenxml.com/archives/xsl-list/200612/msg00018.html. [Último acceso: 14 Enero 2018].

--

--