The first of these gives a simple if... then... construct. The next three provide the equivalent of if... then... else... and the switch statement in many languages, and the last provides looping.
<xsl:if>
This element is used within a template purely to make execution of the enclosed statements conditional on the result of a test. It has a mandatory test attribute, which contains an expression that will return a Boolean result. The enclosed statements will be executed if the result of the test is true.
The test expression may involve the use of XSLT functions. We shall cover a couple of the functions included in XSLT at the end of this chapter, but their use in the following code is self-explanatory.
Common uses for <xsl:if> are testing for error conditions, or treating the first or last elements of a collection differently from the others. For example, the following template (ListCharacters.xsl) lists all the characters in Hamlet, placing a comma and space after all but the last:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="PLAY">
<HTML xmlns="http://www.w3.org/TR/REC-html40">
<HEAD>
<TITLE>Listing Characters</TITLE>
</HEAD>
<BODY>
<P>
The characters in Hamlet are:
<xsl:for-each select="//PERSONA">
<xsl:value-of select="."/>
<xsl:if test = "position() != last()">, </xsl:if>
</xsl:for-each>
</P>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
And this is the result after being applied to Hamlet.xml:

Note that this element only allows an if... then...; if we want an else..., we must use <xsl:choose>, which we will look at next.
<xsl:choose>, <xsl:when>, and <xsl:otherwise>
These elements provide the equivalent of a switch statement, and can therefore also be used to provide an if... then... else... construct.
Here is an example of them in use in HamletWithLines.xsl, which is modified from a previous stylesheet (Hamlet.xsl):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="*|/"><xsl:apply-templates/></xsl:template>
<xsl:template match="text()|@*"><xsl:value-of select="."/></xsl:template>
<xsl:template match="EXTRACT">
<HTML xmlns="http://www.w3.org/TR/REC-html40">
<HEAD>
<TITLE>Hamlet</TITLE>
</HEAD>
<BODY>
<xsl:apply-templates/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="ACT/TITLE"><H1><xsl:value-of select="."/></H1>
</xsl:template>
<xsl:template match="SCENE/TITLE"><H2><xsl:value-of select="."/></H2>
</xsl:template>
<xsl:template match="STAGEDIR"><P><I><xsl:value-of select="."/></I></P>
</xsl:template>
<xsl:template match="SPEAKER"><DIV><xsl:value-of select="."/></DIV>
</xsl:template>
<xsl:template match="LINE[position()=last()]">
<DIV>
<xsl:value-of select="."/>
<xsl:choose>
<xsl:when test="../SPEAKER='BERNARDO'">
<HR style="color:silver"/>
</xsl:when>
<xsl:when test="../SPEAKER='FRANCISCO'">
<HR style="color:black"/>
</xsl:when>
<xsl:otherwise> <!-- this is the trap for unrecognized speakers -->
<DIV style="color:silver">
!! oops, I don't know this speaker !!
</DIV>
</xsl:otherwise>
</xsl:choose>
</DIV>
</xsl:template>
<xsl:template match="LINE"><xsl:value-of select="."/></xsl:template>
</xsl:stylesheet>
I have added the <xsl:output> element and HTML namespace that we did not know about earlier. But the important part is the new template, which simply puts a different shade of horizontal rule under the last line of each speech, depending on the speaker. This is how it looks when applied to HamletExtract.xml:

In my first attempt at this stylesheet, I misspelled the name "FRANCISCO" as "FRANSISCO" in the new template. This was the result:

As you can see, the <xsl:otherwise> can be used to trap errors, as it has done here.
Continued...