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 Expression | Meaning |
|---|---|
| price > 100 | Price is greater than 100 |
| stock = 0 | Stock 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) > 10 | Name 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
| Feature | xsl:if | xsl:choose |
|---|---|---|
| Number of conditions | One | Multiple |
| Else clause | No | Yes — xsl:otherwise |
| Mutually exclusive | N/A | Yes — only first match fires |
| Best for | Simple show/hide logic | Grading, 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 <, > written as >.
