|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV |
TODAY'S TOP SOA & WEBSERVICES LINKS XML Protocols XSL 101: XSL Functionality
XSL 101: XSL Functionality
By: Frank Neugebauer
Feb. 4, 2001 12:00 AM
In my last article, "Two Great Technologies, One Amazing Solution" (XML-J, Vol. 2, issue 1), I demonstrated how the Java programming language could be used within stylesheets to add robustness to XSLT. This month I'll stick strictly within the confines of the XPath and XSLT to show some of the built-in functionality available to you. The XPath and XSLT specifications include sections defining "functions." Whether they're core (required by an implementation of the spec) or external (core extensions or user defined), functions assist the stylesheet writer by providing valuable services such as node value formatting and node set metainformation. In this article I'll explain some of the general syntax rules for using functions and provide examples of the more common types. This article assumes you have a basic knowledge of XSLT and XSL stylesheets. It's also assumed that those who want to try the examples have a suitable XSLT execution environment, such as Apache Xalan.
W3C Specifications FunctionCall ::= FunctionName'('(Argument(','Argument)*)?')' FunctionCall is identified by its FunctionName and can contain (optional comma-separated) Arguments that are Expr(essions). Basically, this means that functions have predefined names, return single values, and can have arguments that are one of the four XSL object types: node-set, Boolean, number, and string. If more than one argument is required, they must be comma-separated. Also, arguments are automatically converted to the proper data type, if possible. For example, if the argument is a number and the node value provided is the string "50," that string is converted to a number. It's a problem if the argument can't be converted or if you supply the wrong number of arguments when calling a function. Functions are generally used within selection statements to either manipulate (not alter) the value of the element or add robustness to the selection criteria. For example, if I wanted to convert the value of a node selection to a number, I could use the number function as follows: <xsl:value-of select="number(ANUMBER)"/>This XSL would convert the element "ANUMBER" to a number. If the value of the element isn't a number, an error will occur. Similarly, I could use the position function to match every instance of a particular element except the first, as follows: <xsl:template match="STUFF[position() > 1]"/>This would limit the node-set match of "STUFF" by matching elements that have a position (with respect to all "STUFF" elements) greater than 1 (the first occurrence).
Types of Functions Now that you have a basic backdrop, I'll show more concrete examples of some of the functions listed in Table 1. For functions without concrete examples, I recommend checking the specification before using them, since some functions may produce unexpected results. For the sake of simplicity, I'll use the same XML (see Listing 1) and XSL (see Listing 2) documents to demonstrate all the functions covered. The number count(node-set) Function The count function will return a number representing the total number of nodes in the node-set supplied as an argument. This function has many uses, such as determining the total number of items within an invoice: <xsl:value-of select="count(//ITEM)"/>This will output the total ITEM elements contained within the source XML document (see Listing 1). The number sum(node-set) Function The sum function has a particular usefulness: incremental addition. Al- though you can use the mathematical "+" operator within stylesheets, you can't modify the value of a variable for the purpose of adding together several elements. This is because the specification doesn't allow for the modification of "variables." The implication is that you can't simply navigate through a node-set and increment a "sum" as you go. The good news is that the sum function will do this for you. The only real "trick" is to use XPath to select the correct nodes to pass as the node-set argument. Let's say I wanted to generate a grand total for all the items within an invoice (again, see Listing 1). The sum function makes this simple, as demonstrated with the following snippet taken from Listing 2: <xsl:value-of select="sum(//PRICE)"/>The result is 314.96000000000004. It works, but the format is probably inappropriate for display in a Web page. If only there were a way to format that number... The string format-number(number, string, string?) Function This function will take the number argument and format it using the format pattern supplied as the second argument. If you want to create a decimal format other than the default (I guess this would be an uncommon situation), you can (optionally) supply the QName (see the specification for clarification) of another as the third argument. Not providing a third argument implies that you've chosen to use the default provided by the processor implementation. The result is a formatted string. The format-number function has its roots in Java. Specifically, the format pattern (second argument) is based on the Java Development Kit (JDK) version 1.1 DecimalFormat class. Borrowing the structure from page 459 of Michael Kay's XSLT Programmer's Reference, I provided some examples of valid formats in Table 2. Notice how the last two patterns provide for both positive and negative number formats. This can be particularly helpful and avoid conditional logic within your stylesheets. Imagine conditionally checking for negative values and appending "CR" at the end. For example: <xsl:variable name="foo" That's a lot of XSL for something so easily handled with the format-number. That would be crazy. Okay, so I've done that before, but only because I didn't want you to have to. Seriously, though, as an example of format-number, I'll format the result of the sum shown in the previous section. What I'm doing is chaining the functions together. Just like mathematics and programming languages, functional expressions are evaluated from the inner parenthesis out. Therefore: <xsl:value-of select="format-number(sum(//PRICE), '$#,##0.00')"/>will first compute the sum, then apply the format. In other words the sum function is executed first (inner parenthesis), then the format-number function (outer parenthesis). The result is a nicely formatted $314.96. Imagine doing that without the format-number. No, I haven't done that too! The string concat(string, string, string*) Function The concat function simply returns the concatenation of the string arguments. The first two strings are required, with the last being present zero or more times. This means you can supply any number (greater than or equal to two) of arguments to concat. In the example, I'll combine the first occurrence of the ID and DESC elements to output a unique identifier for that ITEM. This is done using this concat function: <xsl:value-of select="concat(//ITEM[1]/ID, //ITEM[1]/DESC)"/> The result is "S072796Item 1". Listing 3 shows the complete output of transforming the XML in Listing 1 using the XSL stylesheet in Listing 2.
Conclusion
Resources
YOUR FEEDBACK
XML JOURNAL LATEST STORIES . . .
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK BREAKING XML NEWS
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||