XSLT: применять шаблоны с условными параметрами?
-
05-07-2019 - |
Вопрос
Я хотел бы применить шаблон с различными параметрами на основе результата условия. Примерно так:
<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>
Прежде всего, я подозреваю, что это можно решить намного, намного лучше. (Я совершенно новичок в XSLT, поэтому, пожалуйста, предложите улучшения и простите раздутый код.)
Теперь к вопросу: как я мог установить параметры, основанные на этом условном выражении, и все же использовать их в xsl: apply-templates
? Я попытался обернуть весь xsl: choose
с помощью xsl: apply-templates
start- / end-tag, но это явно не разрешено. Есть какие-нибудь подсказки?
Решение
Альтернативный метод - поместить операторы xsl: select в элементы 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>
Другие советы
В вашем методе нет ничего плохого, но вы также можете добавить свое условие в атрибут xsl: template match
. Это приведет только к одному xsl: apply-templates
, но нескольким элементам xsl: template
Вы можете избавиться от всей этой логики и режимов, извлекая ваши условия в предикаты. Вы не говорите, как называется элемент, с которым вы имеете дело, но при условии, что он называется foo
, тогда должно хватить чего-то подобного:
<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>