Putting Expressions to Work

Similar to patterns, expressions play an important role in determining how XSLT style sheets transform XML content. However, expressions differ from patterns in that expressions are capable of carrying out programmatic operations such as comparisons and calculations. Expressions are created using patterns and additional XSLT constructs such as comparison operators and functions. The next couple of sections explain how to use these constructs to create XSLT expressions.

Working with Operators

Earlier in the tutorial you learned how to use the xsl:if and xsl:when elements to add conditional logic to XSLT style sheets. What you didn't learn, however, was how powerful the actual conditional test of these elements can be. Both of these elements rely on an attribute named test to specify a conditional expression that essentially results in a value of true or false; if the resulting value is true, the associated XSLT code is carried out. The specific expression used by the test attribute is quite flexible and can involve several different comparison operators. Following are some of the most commonly used comparison operators that can appear within the test attribute:

  • = Checks to see if two pieces of data are equal

  • != Checks to see if two pieces of data are unequal

  • < Checks to see if one piece of data is less than another

  • <= Checks to see if one piece of data is less than or equal to another

  • > Checks to see if one piece of data is greater than another

  • >= Checks to see if one piece of data is greater than or equal to another

  • and Checks to see if two conditional expressions are both true

  • or Checks to see if at least one of two conditional expressions is true

By the Way

Although the less-than and greater-than operators look strange at first, upon closer inspection you can see that they are actually just entities. If you recall, an entity is identified by sandwiching its name between an ampersand (&) and a semicolon (;). So, the greater-than-or-equal-to operator, which is specified as >=, is ultimately resolved into >=.

To use these operators, you simply combine them with patterns and literal values to create expressions. For example, the following code shows how to create an xsl:if element that invokes a section of code only if the content of the child element named countdown is less than or equal to zero:

<xsl:if test="countdown &lt;= 0">
  Lift off!

The and and or operators carry out a logical comparison between two other expressions that must evaluate to a true or false value. As an example, if you wanted to expand the countdown example so that you could count in either direction, the following code would do the trick:

<xsl:if test="countdown &lt;= 0 or countdown &gt; 10">
  Lift off!

The or operator used in this example causes "lift-off" to occur if the value of countdown is either less than or equal to zero, or greater than 10. This example demonstrates how multiple comparison operators can be used together to create more powerful conditional expressions.

In addition to comparison operators, there are also a few familiar math operators that you may find useful:

  • * Multiplies two numeric values

  • div Divides two numeric values and returns the integer result

  • mod Divides two numeric values and returns the integer remainder

  • + Adds two numeric values

  • - Subtracts two numeric values

These operators can be used in expressions to perform math operations on XML data. Following is an example of how you might multiply the contents of two child elements (quantity and unitprice) in order to calculate a shopping cart total that is displayed in an XHTML document:

  Total price = <xsl:value-of select="quantity * unitprice"/>

This code reveals the flexibility of the select attribute and how a math operator can be used within it to carry out simple calculations. The values stored in the quantity and unitprice child elements are multiplied using the multiplication operator (*).

The result of the multiplication is inserted into the output document as the content of an XHTML div element.

Using Standard Functions

If you thought operators were neat, you will be really impressed with the standard functions built into XSLT. These functions are much more interesting than operators because they carry out calculations that would otherwise be quite tedious using simple math operators alone. Following are some of the more commonly used standard functions supported in XSLT:

  • ceiling() Round up a decimal value to the nearest integer

  • floor() Round down a decimal value to the nearest integer

  • round() Round a decimal value to the nearest integer

  • sum() Add a set of numeric values

  • count() Determine the quantity of values in a set

Although these functions are somewhat self-explanatory in terms of what kinds of calculations they carry out, it doesn't hurt to see a few of them at work in the context of a style sheet. Following is an example of how you might add up the values of a set of nodes to calculate a total with the sum() function:

  Total amount = $<xsl:value-of select="sum(cart/item/@price)"/>

This example would work well for a shopping cart XML document that includes a cart element that holds several item elements representing each item in the shopping cart. Notice that the price attribute of each item element is used as the basis for the sum calculation. Following is an example of the kind of XML code that could be transformed using this XSLT example:

  <item price="199.99">
  DVD Player
  <item price="699.99">
  32-Inch Television
  <item price="249.99">
  Surround-Sound Speaker System

When applied to this code, the previous XSLT example adds together the prices of the three items to arrive at a total of 1149.97. This shopping cart example could also benefit from knowing how many items are in the shopping cart, which is accomplished with the following code:

  Number of items = <xsl:value-of select="count(cart/item)"/>

The count() function is used in this example to count the number of item elements contained within the cart element. As this example demonstrates, the standard functions built into XSLT allow you to perform very useful computations with little effort.