XSLT conditional processing

If we want to process an element only if a condition is verified, we can use the xsl:if tag. If we need something more sophisticated, we have a more complex alternative, based on the xsl:choose tag, similiar to the C switch construct.

Let's show the usage of both of them with a couple of examples. As a base for them we'll use this XML:

<?xml version="1.0" encoding="UTF-8"?>
<Characters>
<Character age="99">Julius Caesar</Character>
<Character age="23">Anne Boleyn</Character>
<Character age="41">George Washington</Character>
<Character age="45">Martin Luther</Character>
<Character age="800">Methuselah</Character>
<Character age="119">Moses</Character>
<Character age="50">Asterix the Gaul</Character>
</Characters>

A list of characters, each of them having an attribute, age, that we want to use as a selector for taking a decision.

xsl:if

Here we want to generate an HTML file containing all the Character elements having a suspicious age, more than 110. Like this:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Age check on Characters.</title>
</head>
<body>
<h3>The recorded age is unusually high.</h3>
<p><b>Methuselah</b> is older than expected.
Please check if <b>800</b> is correct.
</p>

<p><b>Moses</b> is older than expected.
Please check if <b>119</b> is correct.
</p>
</body>
</html>

This is an XSLT that we could use for that:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<head>
<title>Age check on Characters</title>
</head>
<body>
<h3>The recorded age is unusually high.</h3>
<xsl:apply-templates select="/Characters/Character"/>
</body>
</html>
</xsl:template>

<xsl:template match="Character">
<xsl:if test="@age &gt; 110 ">
<p><b><xsl:value-of select="."/></b> is older than expected.
Please check if <b><xsl:value-of select="@age"/></b> is correct.</p>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

In the "test" attribute of the xsl:if tag we check a condition. And when it is true, we actually put in the resulting document the content of the tag. Notice that we specify age as an attribute of the current element (using @) and that we can't use directly the greater ('>') symbol.

xsl:choose

We want now generating an HTML a bit more complex, something like that:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Age check on all Characters</title>
</head>
<body>
<h3>The following is the assessment of the age data.</h3>
<p><b>Julius Caesar</b> - ok.</p>
<p><b>Anne Boleyn</b> - ok.</p>
<p><b>George Washington</b> - ok.</p>
<p><b>Martin Luther</b> - ok.</p>
<p><b>Methuselah</b> - please check if<b>800</b>, is the correct age.</p>
<p><b>Moses</b> - please check if <b>119</b>, is the correct age.</p>
<p><b>Asterix the Gaul</b> - ok.</p>
</body>
</html>

So, if the age is suspiscious, we generate an alert as before, otherwise we tell the user that character looks good to us.

This is the XSLT I have used to generate that document:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<html>
<head>
<title>Age check on all Characters</title>
</head>
<body>
<h3>The following is the assessment of the age data.</h3>
<xsl:apply-templates select="/Characters/Character"/>
</body>
</html>
</xsl:template>

<xsl:template match="Character">
<xsl:choose>
<xsl:when test="@age &gt; 110 ">
<p><b><xsl:value-of select="."/></b> - please check if
<b><xsl:value-of select="@age"/></b> is the correct age.</p>
</xsl:when>
<xsl:otherwise>
<p><b><xsl:value-of select="."/></b> - ok.</p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>

The test is performed exactely as in the xsl:if, but the structure is a bit more complex. We have a xsl:choose tag that includes an xsl:when, working as the xsl:if, but used in conjunction with an xsl:otherwise specifying the alternative path.

More information on XSLT and Saxon in chapter eight of Beginning XML by David Hunter et al. (Wrox).

No comments:

Post a Comment