page 58 xsl:if test=false
Another trick example; this
test
attribute is always
true
. As before, we used single quotes inside double quotes to specify that this is a literal string. Because the string
has a length greater than zero, the
test
attribute is always
true
. The value of the nonempty string, confusing as it is, doesnt matter.
xsl:if test=not3
This
test
attribute is always
false
. The literal
3
evaluates to
true
, so its negation is
false
. On the other hand, the expressions
not0
and
not-0
are always
true
.
xsl:if test=false
This
test
attribute is always
false
. The boolean function
false
always returns the boolean value
false
.
xsl:if test=sectionsection
The XPath expression
sectionsection
returns a node-set. If the current context contains one or more
section
elements that contain a
section
element in turn, the
test
attribute is
true
. If no such elements exist in the current context, the
test
attribute is
false
.
4.2.2 The xsl:choose Element
The
xsl:choose
element is the equivalent of a
case
or
switch
statement in other programming languages. You can also use it to implement an if-then-else statement. An
xsl:choose
contains at least one
xsl:when
element logically equivalent to an
xsl:if
element, with an optional
xsl:otherwise
element. The
test
attribute of each
xsl:when
element is evaluated until the XSLT processor finds one that evaluates to
true
. When that happens, the contents of that
xsl:when
element are evaluated. If none of the
xsl:when
elements have a test that is
true
, the contents of the
xsl:otherwise
element if there is one are processed.
Heres how these XSLT elements compare to the
switch
or
selectcase
statements you might know from other languages:
•
The C, C++, and Java switch statement is roughly equivalent to the xsl:choose element. The one exception is that procedural languages tend to use fallthrough
processing. In other words, if a branch of the switch statement evaluates to true, the runtime executes everything until it encounters a break statement, even if some of that
code is part of other branches. The xsl:choose element doesnt work that way. If a given xsl:when evaluates to true, only the statements inside that xsl:when are
evaluated.
•
The Java
case
statement is equivalent to the
xsl:when
element. In Java, if a given
case
statement does not end with a
break
statement, the following case is executed as well. Again, this is not the case with XSLT; only the contents of the first
xsl:when
element that is
true
are processed.
•
The Java and C++
default
statement is equivalent to the
xsl:otherwise
element.
page 59
4.2.2.1 xsl:choose example
Heres a sample
xsl:choose
element that sets the background color of the tables rows. If the
bgcolor
attribute is coded on the
table-row
element, the value of that attribute is used as the color; otherwise, the sample uses the
position
function and the
mod
operator to cycle the colors between
papayawhip
,
mintcream
,
lavender
, and
whitesmoke
.
xsl:template match=table-row tr
xsl:attribute name=bgcolor xsl:choose
xsl:when test=bgcolor xsl:value-of select=bgcolor
xsl:when xsl:when test=position mod 4 = 0
xsl:textpapayawhipxsl:text xsl:when
xsl:when test=position mod 4 = 1 xsl:textmintcreamxsl:text
xsl:when xsl:when test=position mod 4 = 2
xsl:textlavenderxsl:text xsl:when
xsl:otherwise xsl:textwhitesmokexsl:text
xsl:otherwise xsl:choose
xsl:attribute xsl:apply-templates select=
tr xsl:template
In this sample, we use
xsl:choose
to generate the value of the
bgcolor
attribute of the
tr
element. Our first test is to see if the
bgcolor
attribute of the
table-row
element exists; if it does, we use that value for the background color and the
xsl:otherwise
and other
xsl:when
elements are ignored. If the
bgcolor
attribute is coded, the XPath expression
bgcolor
returns a node-set containing a single attribute node. The next three
xsl:when
elements check the position of the current
table-row
element. The use of the
mod
operator here is the most efficient way to cycle between the various options. Finally, we use an
xsl:otherwise
element to specify
whitesmoke
as the default case. If
position mod 4 = 3
, the background color will be
whitesmoke
. A couple of minor details: in this example, we could replace the
xsl:otherwise
element with
xsl:when test=position mod 4 = 3
; that is logically equivalent to the example as coded previously. For obfuscation bonus points, we could code the second
xsl:when
element as
xsl:when test=notposition mod 4
. Remember that the boolean negation of zero is
true
.
4.2.3 The xsl:for-each Element
If you want to process all the nodes that match a certain criteria, you can use the
xsl:for- each
element. Be aware that this isnt a traditional
for
loop; you cant ask the XSLT processor to do something like this:
for i = 1 to 10 do
The
xsl:for-each
element lets you select a set of nodes, then do something with each of them. Let me mention again that this is not the same as a traditional
for
loop. Another important point is that the current node changes with each iteration through the
xsl:for- each
element. Well go through some examples to illustrate this.