Al escribir filtros XSLT es posible usar variables como en lenguajes tradicionales de programación, de modo de simplificar el código y optimizar algunos procesos.
Sin embargo hay algunas diferencias fundamentales a tomar en cuenta que pueden complicar la vida del usuario.
Descripción
En XSLT, el tag para asignar variables es
<xsl:variable name="nombre_de_la_variable" select="expresionXPath"/>
Donde por supuesto la “expresionXPath” corresponde al valor que se quiere asignar. De esta manera podemos usar la variable de las siguientes formas:
- Usando <xsl:value-of select=”$nombre_de_la_variable” />
- Concatenando con, por ejemplo, valores de argumentos en el HTML que se quiere generar. Por ejemplo,
<div class="menuitem-{$nombre_de_la_variable}">...
- En cualquier expresión XPath llamandola siempre como $nombre_de_la_variable.
Como se puede apreciar, se obtiene el valor almacenado llamando al nombre de la variable con el signo $ delante. En el caso de la concatenación la clave está en las llaves (“{}”) que rodean la expresión.
Scope (alcance) y cambio de valor
Un punto muy importante a tomar en cuenta es donde existe la variable como tal. En este sentido, el scope de la variable es el tag que la contiene. Miremos la siguiente expresión:
... <xsl:choose> <xsl:when test="condicion1"> <xsl:variable name="mi_variable" select="hola que tal"/> </xsl:when> <xsl:otherwise> <xsl:variable name="mi_variable" select="festival" /> </xsl:otherwise> </xsl:choose> La variable vale: <xsl:value-of select="$mi_variable">
A diferencia de lo que podría esperarse, el resultado obtenido será
La variable vale:
Esto se debe a que el scope de la variable es el tag que la contiene, en este caso un <xsl:when>. Ante esto podríamos aplicar lógica de programación tradicional, definiendo la variable fuera del <xsl:choose> de modo de asegurarnos de aumentar su alcance haciéndola existir fuera del bloque.
El código quedaría
... <xsl: variable name="mi_variable" select="" /> <xsl:choose> <xsl:when test="condicion1"> <xsl:variable name="mi_variable" select="hola que tal"/> </xsl:when> <xsl:otherwise> <xsl:variable name="mi_variable" select="festival" /> </xsl:otherwise> </xsl:choose> La variable vale: <xsl:value-of select="$mi_variable">
Esto tampoco funciona, dado que pasa a funcionar otro elemento importante (y para algunos más que extraño) de XSLT: no se puede cambiar el valor de una variable. Da lo mismo donde la definamos, la variable aparece como siendo creada nuevamente, con el scope dentro del <xsl:when>.
Asignación condicional
Para saltarnos esta limitante y efectivamente darle un valor a la variable dependiendo de alguna condición, podemos usar una sintaxis alternativa, en que en lugar de usar un select para la asignación, damos el valor dependiendo de los hijos del tag, como en el siguiente ejemplo:
<xsl:variable name="mi_variable"> <xsl:choose> <xsl:when test="condicion1">hola que tal</xsl:when> <xsl:otherwise>festival"</xsl:otherwise> </xsl:choose> </xsl:variable> La variable vale: <xsl:value-of select="$mi_variable">
Ahora si obtenemos
La variable vale: hola que tal
ó
La variable vale: festival
dependiendo de la condición. Sin embargo, como decíamos anteriormente, una vez que fue asignada la variable no puede ser modificada.
Referencias
Sección sobre variables de un muy buen FAQ de XSLT De paso justifican la no reasignación de variables como parte de un buen esquema de programación.