Me sale el error de que la hoja de estilo no se puede compilar. El valor del modo debe ser un QName, pero es "{$ mode}".
¿Existe la posibilidad de utilizar modos dependientes de variables?
No, esto no es compatible con ninguna versión XSLT - 1.0, 2.0 o 3.0.
Como usted está tratando de hecho para emular funciones de orden superior (HOF), es posible utilizar el principio subyacente de FXSL hacer esto en XSLT 1.0.
FXSL 1.x es una biblioteca de plantillas escritas en XSLT 1.0 puro que admite/emula HOF.
Aquí es una solución completa basada en estos principios:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net" exclude-result-prefixes="f">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<f:inc/>
<f:double/>
<xsl:variable name="vModeInc" select="document('')/*/f:inc[1]"/>
<xsl:variable name="vModeDouble" select="document('')/*/f:double[1]"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<nums>
<xsl:apply-templates select="$vModeInc">
<xsl:with-param name="pNodes" select="node()"/>
</xsl:apply-templates>
</nums>
==============
<nums>
<xsl:apply-templates select="$vModeDouble">
<xsl:with-param name="pNodes" select="node()"/>
</xsl:apply-templates>
</nums>
</xsl:template>
<xsl:template match="f:inc">
<xsl:param name="pNodes"/>
<xsl:apply-templates select="$pNodes" mode="incr"/>
</xsl:template>
<xsl:template match="f:double">
<xsl:param name="pNodes"/>
<xsl:apply-templates select="$pNodes" mode="double"/>
</xsl:template>
<xsl:template match="num" mode="incr">
<num><xsl:value-of select=".+1"/></num>
</xsl:template>
<xsl:template match="num" mode="double">
<num><xsl:value-of select=".*2"/></num>
</xsl:template>
</xsl:stylesheet>
Cuando se aplica esta transformación en el siguiente documento XML:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
el resultado deseado, correcta es producido - los elementos nums/num
procesados en uno (cada uno) de los dos modos disponibles, de pendiente en la variable especificada - $vModeInc
(1 añadido a cada valor) o $vModeDouble
(cada valor se multiplica por dos):
<nums>
<num>2</num>
<num>3</num>
<num>4</num>
<num>5</num>
<num>6</num>
<num>7</num>
<num>8</num>
<num>9</num>
<num>10</num>
<num>11</num>
</nums>
==============
<nums>
<num>2</num>
<num>4</num>
<num>6</num>
<num>8</num>
<num>10</num>
<num>12</num>
<num>14</num>
<num>16</num>
<num>18</num>
<num>20</num>
</nums>
Lo que se quiere hacer es sintácticamente incorrecto, pero es posible * * en XSLT 1.0 para lograr el mismo efecto, utilizando el principio de "referencia de plantilla" que es la base de la biblioteca FXSL. –
¡Gracias por esta idea! Traté de entenderlo, pero soy nuevo en XSLT y no tengo mucha experiencia con programación funcional. Para el caso descrito, es "sobre ingeniería". Tal vez, pueda usarlo algunas veces, cuando tenga más experiencia con él. – maria90
maria90, basta con saber que existe tal técnica, y luego usarla siempre que sea necesario. –