XSLT BASICS PART 4 - CONTROL FLOW ELEMENTS
DESCRIPTION
The following five elements allow us to control execution within a template in a manner analogous to procedural languages. These are <xsl:if>, <xsl:choose>, <xsl:when>, <xsl:otherwise>, and <xsl:for-each>.
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<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:


Leave a Reply