XSLT: ¿Aplicar plantillas con parámetros condicionales?
-
05-07-2019 - |
Pregunta
Me gustaría aplicar una plantilla con diferentes parámetros en función del resultado de un condicional. Algo como esto:
<xsl:choose>
<xsl:when test="@attribute1">
<xsl:apply-templates select='.' mode='custom_template'>
<xsl:with-param name="attribute_name" tunnel="yes">Attribute no. 1</xsl:with-param>
<xsl:with-param name="attribute_value" tunnel="yes"><xsl:value-of select="@attribute1"/></xsl:with-param>
</xsl:apply-templates>
</xsl:when>
<xsl:when test="@attribute2">
<xsl:apply-templates select='.' mode='custom_template'>
<xsl:with-param name="attribute_name" tunnel="yes">Attribute no. 2</xsl:with-param>
<xsl:with-param name="attribute_value" tunnel="yes"><xsl:value-of select="@attribute1"/></xsl:with-param>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select='.' mode='custom_template'>
<xsl:with-param name="attribute_name" tunnel="yes">Error</xsl:with-param>
<xsl:with-param name="attribute_value" tunnel="yes">No matching attribute </xsl:with-param>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
En primer lugar, sospecho que esto podría resolverse de una manera mucho mejor. (Soy completamente nuevo en XSLT, así que sugiera mejoras y perdone el código abultado).
Ahora, para la pregunta: ¿cómo podría establecer los parámetros basados ??en este condicional, y aún los he usado en un xsl: apply-templates
? He intentado envolver todo el xsl: choice
con una etiqueta de inicio / fin xsl: apply-templates
, pero aparentemente no es legal. ¿Alguna pista?
Solución
Un método alternativo sería colocar las sentencias xsl: choice dentro de los elementos xsl: param
<xsl:apply-templates select="." mode="custom_template">
<xsl:with-param name="attribute_name" tunnel="yes">
<xsl:choose>
<xsl:when test="@attribute1">Attribute no. 1</xsl:when>
<xsl:when test="@attribute2">Attribute no. 2</xsl:when>
<xsl:otherwise>Error</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="attribute_value" tunnel="yes">
<xsl:choose>
<xsl:when test="@attribute1"><xsl:value-of select="@attribute1"/></xsl:when>
<xsl:when test="@attribute2"><xsl:value-of select="@attribute1"/></xsl:when>
<xsl:otherwise>No matching attribute </xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:apply-templates>
Otros consejos
No hay ningún problema con su método, pero también puede agregar su condicional al atributo xsl: template match
. Esto conducirá a un solo xsl: apply-templates
, pero a varios elementos xsl: template
Puedes deshacerte de toda esa lógica y los modos extrayendo tus condiciones en predicados. No dice cuál es el nombre del elemento con el que está tratando, pero suponiendo que se llame foo
, algo como esto debería ser suficiente:
<xsl:template match="foo[@attribute1]">
<!--
do stuff for the case when attribute1 is present
(and does not evaluate to false)
-->
</xsl:template>
<xsl:template match="foo[@attribute2]">
<!--
do stuff for the case when attribute2 is present
(and does not evaluate to false)
-->
</xsl:template>
<xsl:template match="foo">
<!--
do stuff for the general case
(when neither attribute1 nor attribute 2 are present)
-->
</xsl:template>