XSLT If and Choose

Real-world XML data contains variation. Some products are on sale; others are not. Some employees have a manager; others do not. XSLT provides xsl:if for single conditions and xsl:choose for multiple conditions, so your transformation can respond to data dynamically.

xsl:if — Single Condition

xsl:if tests a condition. The content inside the element renders only when the test is true. There is no else clause — for that, use xsl:choose.

<xsl:if test="XPath-expression">
  <!-- rendered only if condition is true -->
</xsl:if>

Example: Show a badge for items in stock

XML Source
<products>
  <product><name>Notebook</name><stock>50</stock><price>40</price></product>
  <product><name>Stapler</name><stock>0</stock><price>120</price></product>
  <product><name>Pen Pack</name><stock>200</stock><price>25</price></product>
</products>
XSLT
<xsl:for-each select="products/product">
  <p>
    <xsl:value-of select="name"/> — INR <xsl:value-of select="price"/>
    <xsl:if test="stock > 0">
      <strong> [In Stock]</strong>
    </xsl:if>
  </p>
</xsl:for-each>
Output
Notebook — INR 40 [In Stock]
Stapler — INR 120
Pen Pack — INR 25 [In Stock]

Common xsl:if Test Patterns

Test ExpressionMeaning
price > 100Price is greater than 100
stock = 0Stock equals zero
@status = 'active'Status attribute is "active"
not(email)The email element does not exist
position() = last()Current item is the last in the loop
string-length(name) > 10Name is longer than 10 characters
contains(role, 'Manager')Role contains the word "Manager"

xsl:choose — Multiple Conditions

xsl:choose handles multiple mutually exclusive conditions. It works like a switch statement or an if-else if-else chain.

<xsl:choose>
  <xsl:when test="condition1">
    <!-- output when condition1 is true -->
  </xsl:when>
  <xsl:when test="condition2">
    <!-- output when condition2 is true -->
  </xsl:when>
  <xsl:otherwise>
    <!-- output when none of the above is true -->
  </xsl:otherwise>
</xsl:choose>

Only one branch fires — the first xsl:when whose test passes. xsl:otherwise is optional.

Example: Color-Code Exam Results

XML Source
<results>
  <student><name>Ananya</name><marks>91</marks></student>
  <student><name>Bharat</name><marks>74</marks></student>
  <student><name>Chitra</name><marks>55</marks></student>
  <student><name>Dinesh</name><marks>38</marks></student>
</results>
XSLT
<xsl:for-each select="results/student">
  <p>
    <xsl:value-of select="name"/> — <xsl:value-of select="marks"/> —
    <xsl:choose>
      <xsl:when test="marks >= 90">Grade: A+ (Distinction)</xsl:when>
      <xsl:when test="marks >= 75">Grade: A (First Class)</xsl:when>
      <xsl:when test="marks >= 60">Grade: B (Second Class)</xsl:when>
      <xsl:when test="marks >= 40">Grade: C (Pass)</xsl:when>
      <xsl:otherwise>Grade: F (Fail)</xsl:otherwise>
    </xsl:choose>
  </p>
</xsl:for-each>
Output
Ananya — 91 — Grade: A+ (Distinction)
Bharat — 74 — Grade: B (Second Class)
Chitra — 55 — Grade: C (Pass)
Dinesh — 38 — Grade: F (Fail)

Example: Alternate Row Colors in a Table

<xsl:for-each select="employees/employee">
  <xsl:choose>
    <xsl:when test="position() mod 2 = 0">
      <tr style="background-color:#f0f0f0">
        <td><xsl:value-of select="name"/></td>
      </tr>
    </xsl:when>
    <xsl:otherwise>
      <tr style="background-color:#ffffff">
        <td><xsl:value-of select="name"/></td>
      </tr>
    </xsl:otherwise>
  </xsl:choose>
</xsl:for-each>

Even-numbered rows get a grey background. Odd-numbered rows stay white. The mod operator gives the remainder of division — position() mod 2 equals 0 for every second row.

Combining xsl:if and xsl:choose

<xsl:for-each select="products/product">
  <p>
    <xsl:value-of select="name"/>

    <!-- if the product is on sale -->
    <xsl:if test="@onSale = 'true'">
      <em> (ON SALE!)</em>
    </xsl:if>

    <!-- stock level message -->
    <xsl:choose>
      <xsl:when test="stock > 100"> — Plenty in stock</xsl:when>
      <xsl:when test="stock > 0"> — Limited stock</xsl:when>
      <xsl:otherwise> — Out of stock</xsl:otherwise>
    </xsl:choose>
  </p>
</xsl:for-each>

xsl:if vs xsl:choose

Featurexsl:ifxsl:choose
Number of conditionsOneMultiple
Else clauseNoYes — xsl:otherwise
Mutually exclusiveN/AYes — only first match fires
Best forSimple show/hide logicGrading, categorizing, multi-state logic

Key Points to Remember

  • xsl:if renders content only when its test expression is true.
  • xsl:if has no else clause — use xsl:choose for true/false branching.
  • xsl:choose contains xsl:when branches and an optional xsl:otherwise fallback.
  • Only the first xsl:when whose test is true fires — remaining branches are skipped.
  • xsl:otherwise renders when no xsl:when test passes.
  • Use position() and last() inside conditions to handle first/last items differently.
  • Comparison operators in XSLT: = (equals), != (not equal), < written as &lt;, > written as &gt;.