XSLT: применять шаблоны с условными параметрами? - PullRequest
2 голосов
/ 21 октября 2009

Я хотел бы применить шаблон с другими параметрами, основанными на результате условия. Примерно так:

<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, но это, очевидно, не разрешено законом. Любые подсказки?

Ответы [ 3 ]

10 голосов
/ 21 октября 2009

Альтернативным методом было бы поместить операторы xsl: choose в элементы 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>
3 голосов
/ 21 октября 2009

Вы можете избавиться от всей этой логики и режимов, извлекая ваши условия в предикаты. Вы не говорите, как называется элемент, с которым вы имеете дело, но если предположить, что он называется 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>
3 голосов
/ 21 октября 2009

Ничего плохого в вашем методе, но вы также можете добавить свой условный в атрибут xsl:template match Это приведет только к одному xsl:apply-templates, но нескольким xsl:template элементам

...