9.6. The <xsl:choose> Instruction Element

The <xsl:choose> instruction element allows several conditions to be tested for the selective processing of nodes. Using two child elements, <xsl:when> and <xsl:otherwise>, it provides alternatives to be used for testing and one default if no condition is met. Each test provides a new template for instantiation when the condition for that test is met. The <xsl:choose> element must contain one or more <xsl:when> elements, followed by one optional <xsl:otherwise> element. The <xsl:choose> element does not have any attributes, as shown in the following element model definition:

<!-- Category: instruction -->

<xsl:choose>

  <!-- Content: (xsl:when+, xsl:otherwise?) -->

</xsl:choose>

The <xsl:choose> instruction element offers a significant advantage over <xsl:if>, because <xsl:if> only provides a singular instance of a test resulting in either true or false. On the other hand, <xsl:choose> allows for multiple mutually exclusive conditions, using <xsl:when>, plus a default template, using <xsl:otherwise>, to be instantiated when none of the <xsl:when> elements are chosen. If no <xsl:otherwise> is supplied and no <xsl:when> elements return a value of true, then the template rule is not instantiated.

Note

As a simple reference to programming language structures, <xsl:choose> can be compared with a "case" statement, which provides a test, several possible results, and a default process.


Each <xsl:when> in an <xsl:choose> element is checked until a match is found, or until the default <xsl:otherwise> is reached. Once an <xsl:when> element's test returns true, then no further <xsl:when> elements will be evaluated.

9.6.1. The <xsl:when> Conditional Element

The <xsl:when> element is used within an <xsl:choose> element to stipulate a condition that, when evaluated to a value of true, instantiates the instructions contained in the template. The <xsl:when> element has one required attribute, which is a test attribute, as shown in the following element model definition:

<xsl:when

  test = boolean-expression>

  <!-- Content: template -->

</xsl:when>

The test attribute returns a Boolean true or false, which then determines if the template contained within <xsl:when> will be instantiated. This element must come as the first child to <xsl:choose> (it is only allowed as a child of <xsl:choose>), and there must be at least one <xsl:when> in an <xsl:choose> instruction element or else the stylesheet will be invalid.

9.6.2. The <xsl:otherwise> Contingency Condition

The <xsl:otherwise> provides a default, or contingency, process in the case that any <xsl:when> elements within an <xsl:choose> element fail to return a value of true. The <xsl:otherwise> element accepts no attributes, and its content is a template, as shown in the following element model definition:

<xsl:otherwise>

  <!-- Content: template -->

</xsl:otherwise>

The <xsl:otherwise> element can only appear as a child of <xsl:choose>, and it must be the last child in the <xsl:choose>, preceded by at least one <xsl:when> element. The <xsl:otherwise> provides as its name indicates a set of instructions for what to do "otherwise," when all the <xsl:when> elements have been tested and a true value is not found. It contains a set of instructions that are instantiated if all the <xsl:when> elements preceding it in the <xsl:choose> return Boolean false.

9.6.3. Using <xsl:when> and <xsl:otherwise> with <xsl:choose>

The strength of <xsl:choose> is the ability to add as many <xsl:when> elements as are required to do a proper test. Where <xsl:if> only evaluates one condition to return true or false, <xsl:choose> gives the process additional tests if the first one doesn't match, recursively through the rest of the possible matches. If the same functionality was to be accomplished with <xsl:if>, it would require multiple nested <xsl:if>s for each choice, and additional nested <xsl:if>s with the opposite test to process the options when the <xsl:if>s didn't match. For example, in our first use of <xsl:if>, we had the following rule:

<xsl:if test="block">

To catch any elements that did not match that test, we would need to add another opposite <xsl:if> element, using the not() function as follows:

<xsl:if test="not(block)">

The same functionality in these two instructions can be accomplished with one <xsl:choose>, as shown in Example 9-16.

Example 9-16. Demonstration of the efficiency of <xsl:choose>.
<xsl:choose>
      <xsl:when test="block">
            <xsl:text>Found a block.</xsl:text>
      </xsl:when>
      <xsl:otherwise>
            <xsl:text>Something other than a block was found.
            </xsl:text>
      </xsl:otherwise>
</xsl:choose>

The best part is that you can keep adding tests that are not necessarily opposites, as in Example 9-17.

In this example we've added <xsl:when> elements to “catch” occurrences of sidestreet and boulevard elements, and our <xsl:otherwise> lets us know when we've found something else, this time using the name() function to pull the value of the name of the element. Now we can add instruction elements or LREs as required to create meaningful output for each choice.

Example 9-17. Adding additional <xsl:when> tests to <xsl:choose>.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            version="1.0">

<xsl:template match="text()"/>
<xsl:output indent="yes"/>

<xsl:template match="*">
<xsl:choose>
      <xsl:when test="name() = 'block'">
            <xsl:text>Found a block.
            </xsl:text>
      </xsl:when>
      <xsl:when test="name() = 'sidestreet'">
            <xsl:text>Found a sidestreet.
            </xsl:text>
      </xsl:when>
      <xsl:when test="name() = 'boulevard'">
            <xsl:text>Found a boulevard.
            </xsl:text>
      </xsl:when>
      <xsl:otherwise>
            <xsl:text>Found a </xsl:text>
            <xsl:value-of select="name()"/>
            <xsl:text>.
            </xsl:text>
      </xsl:otherwise>
</xsl:choose>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset