The <xsl:eval> element has no ability to influence structural transformation beyond inserting text. The expr attribute on <xsl:if> and <xsl:when> can be used to exert limited influence over the transformation process from script. A script expression can be executed and return a TRUE/FALSE result. Only if the expression returns TRUE is the contained template executed.
A simple example of arithmetic operations not provided by the XSL Pattern language is testing whether an element index is even or odd. This functionality would enable a ledger-like view in which alternating rows of a table are displayed with different background colors. A conditional with the expr attribute provides a mechanism for performing this calculation in script and using the results to influence the structure of the tree.
Here is some sample data appropriate for our desired ledger display.
<ledger>
<opening-balance>
<date>3/8/98</date>
<category>Opening Balance</category>
<amount>1200.00</amount>
</opening-balance>
<atm>
<number>980309-01</number>
<date>3/9/98</date>
<payee>Gasomatic</payee>
<category>Auto Fuel</category>
<memo>fill-up</memo>
<amount>17.42</amount>
</atm>
<check>
<number>1001</number>
<date>3/9/98</date>
<payee>Boggyfield Apartments</payee>
<category>Rent</category>
<memo>March rent payment</memo>
<amount>1045.00</amount>
</check>
</ledger>
The following style sheet fragment creates a row for each item in the ledger. For even rows it also creates a STYLE attribute and attaches it to the <TR> element to alter the background color.
<TABLE>
<xsl:for-each select="ledger/*">
<TR>
<xsl:if expr="even(this)">
<xsl:attribute name="STYLE">background-color:lightgreen</xsl:attribute>
</xsl:if>
<TD><xsl:value-of select="date"/></TD>
<TD><xsl:value-of select="number"/></TD>
<TD><xsl:value-of select="payee"/></TD>
<TD><xsl:value-of select="category"/></TD>
<TD><xsl:value-of select="memo"/></TD>
</TR>
</xsl:for-each>
</TABLE>
The even function is defined in a script block.
<xsl:script><![CDATA[
function even(e) {
return absoluteChildNumber(e)%2 == 0;
}
]]></xsl:script>
This illustrates a simple test performed from script that influences the transformation by inserting an attribute. More elaborate structural transformations are also possible. The following conditional inserts an entire table row when the balance is negative.
<xsl:if expr="balance < 0">
<TR>
<TD COLSPAN="8" STYLE="background-color:red; color:white; font-weight:bold;
text-align:center">
Overdraft! Please remit <xsl:eval>formatNumber(-balance, "$#,###.00")</xsl:eval>
within 24 hours to avoid returned check fees!
</TD>
</TR>
</xsl:if>
The balance is kept in a global variable named "balance". The expression is evaluated to determine whether the balance is less than zero. If so, the conditional is executed and the row is inserted. Note that the < in the expression must be escaped to conform with XML parsing rules.