XSLT: applicare modelli con parametri condizionali?
-
05-07-2019 - |
Domanda
Vorrei applicare un modello con parametri diversi in base al risultato di un condizionale. Qualcosa del genere:
<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>
Prima di tutto, sospetto che ciò possa essere risolto in un modo molto, molto migliore. (Sono completamente nuovo in XSLT, quindi per favore suggerisci miglioramenti e perdona il codice gonfio.)
Ora per la domanda: come ho potuto impostare i parametri in base a questo condizionale, e ancora usarli in un xsl: apply-templates
? Ho provato a racchiudere l'intero xsl: scegli
con un xsl: apply-templates
tag iniziale / finale, ma apparentemente non è legale. Qualche indizio?
Soluzione
Un metodo alternativo sarebbe quello di inserire le istruzioni xsl: scegliere all'interno degli elementi 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>
Altri suggerimenti
Nulla di sbagliato nel tuo metodo, ma puoi anche aggiungere il tuo condizionale all'attributo xsl: template match
. Questo porterà a un solo elemento xsl: apply-templates
, ma a diversi elementi xsl: template
Puoi liberarti di tutta quella logica e modalità estraendo le tue condizioni in predicati. Non dici quale sia il nome dell'elemento con cui hai a che fare, ma supponendo che si chiami foo
allora qualcosa del genere dovrebbe bastare:
<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>