XSLT: aplique modelos com parâmetros condicionais?
-
05-07-2019 - |
Pergunta
Eu gostaria de aplicar um modelo com parâmetros diferentes com base no resultado de um condicional. Algo assim:
<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>
Primeiro de tudo, suspeito que isso possa ser resolvido de uma maneira muito, muito melhor. (Eu sou totalmente novo no XSLT, então sugira melhorias e perdoe o código inchado.)
Agora, para a pergunta: como eu poderia definir os parâmetros com base nesse condicional e ainda os usava em um xsl:apply-templates
? Eu tentei embrulhar o inteiro xsl:choose
com um xsl:apply-templates
Start-/final, mas isso aparentemente não é legal. Alguma pista?
Solução
Um método alternativo seria colocar o xsl: escolha instruções no xsl: param elements
<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>
Outras dicas
Nada de errado com o seu método, mas você também pode anexar seu condicional a xsl:template match
atributo. Isso levará a apenas um xsl:apply-templates
, mas vários xsl:template
elementos
Você pode se livrar de toda essa lógica e dos modos, extraindo suas condições em predicados. Você não diz qual é o nome do elemento que você está lidando, mas assumindo que se chama foo
Então algo assim deve 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>