Conditional Templates
A version of this page is also available for
4/8/2010
Conditional templates are output only if certain conditions exist within the source document. Conditional templates are defined with the <xsl:if> and <xsl:choose> elements.
In the following portfolio data, the "stock" element has an attribute named "exchange". You might want to generate some output only when this attribute has a certain value.
<?xml version="1.0"?>
<portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes">
<stock exchange="nyse">
<name>zacx corp</name>
<symbol>ZCXM</symbol>
<price dt:dt="number">28.875</price>
</stock>
<stock exchange="nasdaq">
<name>zaffymat inc</name>
<symbol>ZFFX</symbol>
<price dt:dt="number">92.250</price>
</stock>
<stock exchange="nasdaq">
<name>zysmergy inc</name>
<symbol>ZYSZ</symbol>
<price dt:dt="number">20.313</price>
</stock>
</portfolio>
You can easily create another row in the table in which to place the attribute value. However, if you want to indicate stocks from a particular exchange, not by a completely new table row, but by noting them with an asterisk (*). The <xsl:if> element provides a mechanism for conditionally inserting structure into the output tree.
In the following example, the <xsl:if> element inserts an asterisk after the symbol for those stocks listed on the NASDAQ stock exchange. The <xsl:if> contents can be simple text, as in this example, or any structure allowed by XSLT, such as elements or attributes.
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="https://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<HTML>
<BODY>
<TABLE BORDER="2">
<TR>
<TD>Symbol</TD>
<TD>Name</TD>
<TD>Price</TD>
</TR>
<xsl:for-each select="portfolio/stock">
<TR>
<TD>
<xsl:value-of select="symbol"/>
</TD>
<TD><xsl:value-of select="name"/></TD>
<TD><xsl:value-of select="price"/></TD>
</TR>
</xsl:for-each>
</TABLE>
<P>* Listed on Nasdaq stock exchange</P>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
The test attribute takes a pattern. If the query described by the pattern selects one or more nodes, the <xsl:if> template is inserted. If the selection is empty, the conditional is skipped. In this case, the query checks to see if the <stock> element has an exchange attribute, and then verifies that the value of the exchange attribute is equal to "nasdaq". For more information about qualifying a pattern using brackets ([]) and constructing patterns that compare values, see Introduction to the Syntax of XPath.
Choosing Alternatives
The <xsl:choose> element provides a mechanism for "either/or" processing. <xsl:choose> contains a series of <xsl:when> elements that are tested in order from top to bottom until a match is found. An <xsl:otherwise> element can be used to insert a template if no match is found.
The following code can be added to the preceding example to color-code the rows by price. 0-25 are displayed in green; 25-50 are displayed in blue; and 50 or higher are displayed in red. The color is changed by conditionally generating a portion of the value of the STYLE attribute on the table row.
<TR>
<xsl:attribute name="STYLE">color:
<xsl:choose>
<xsl:when test="price[. < 25]">green</xsl:when>
<xsl:when test="price[. < 50]">blue</xsl:when>
<xsl:otherwise>red</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<TD>
...