monksy
monksy

Reputation: 14234

Reducing the need for xsl:if and code duplications

I have XSLT code that differs only by a single class element. However, all of the internal div content.

I attempted to separate out the starting tag as such:

 <xsl:if test="position() = 1">
        <div class="position first">

 </xsl:if>
 <xsl:if test="position() != 1">
        <div class="position">
  </xsl:if>

But ofcourse it produces invalid XSLT code. [The DIV's must be closed within their scope].

Is there another way to add the optional class keyword without have to reduplicate the internal contents?

Upvotes: 3

Views: 62

Answers (3)

JLRishe
JLRishe

Reputation: 101680

Here's an alternative way you can do this without duplicating the use of the "position" class in your XSLT:

<div class="position{substring(' first', 1, 6 * (position() = 1))}">
    <!-- Whatever goes inside the div -->
</div>

And you can do this even more cleanly in XSLT 2.0:

<div class="position{if (position() = 1) then ' first' else ''}">
    <!-- Whatever goes inside the div -->
</div>

Upvotes: 1

Max Toro
Max Toro

Reputation: 28608

Try this:

<div class="position">
   <xsl:if test="position() = 1">
      <xsl:attribute name="class">position first</xsl:attribute>
   </xsl:if>    
</div>

The xsl:attribute instruction should override the literal attribute.

Upvotes: 3

Joel M. Lamsen
Joel M. Lamsen

Reputation: 7173

You can use xsl:choose. A sample template is given below

<xsl:template match="div">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:choose>
            <xsl:when test="position() = 1">
                <xsl:attribute name="class">position first</xsl:attribute>
            </xsl:when>
            <xsl:otherwise>
                <xsl:attribute name="class"><xsl:value-of select="concat('position', position())"/></xsl:attribute>
            </xsl:otherwise>
        </xsl:choose>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

Upvotes: 1

Related Questions