| By Frank Neugebauer | Article Rating: |
|
| February 4, 2001 12:00 AM EST | Reads: |
11,925 |
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
Functions are mentioned variously within the XPath (www.w3c.org/TR/
xpath.html) and XSLT (www.w3.org/TR/xslt.html) specifications. Although the specifications were
written primarily for those wanting to create an implementation
(i.e., Xalan), stylesheet writers can also gain from reading them.
The general function format is mentioned in the XPath specification
(section 3.2):
FunctionCall ::= FunctionName'('(Argument(','Argument)*)?')'
Argument ::= Expr
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
Table 1 is a summary of some of the built-in functions (by
category) listed in the XPath and XSLT specifications. I've included
the prototype, or general syntax, for each. Note: "?" indicates an
optional argument, and "*" indicates zero or more arguments.
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"
select="sum(//PRICE)"/>
<xsl:choose>
<xsl:when test="$foo >= 0">
<xsl:value-of select="$foo"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$foo"/>CR
</xsl:otherwise>
</xsl:choose>
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
The writers of the XPath and XSLT specifications incorporated
a powerful feature in functions. I've demonstrated how functions can
be used to format output (format-number), manipulate element values
(concat and sum), and provide metainformation about a set of nodes
(count). This article has only scratched the surface, so consult the
listed resources (or any other XSL resource) to continue your journey
into XSL functions.
Resources
- XPath Specification: www.w3c.org/TR /xpath.html
- XSLT Specification: www.w3.org/TR/ xslt.html
- Java Development Kit version 1.1 API Documentation for DecimalFormat: http://java.sun.com/products//jdk/1.1/docs/api/java.text.DecimalFormat.html
- Kay, M. (2000). XSLT Programmer's Reference. Wrox Press.
Published February 4, 2001 Reads 11,925
Copyright © 2001 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
About Frank Neugebauer
Frank Neugebauer is a consultant with the Insurance Solutions Group of IBM Global Services. He has been using Java since 1996 and has worked on the architecture and implementation of enterprise Java solutions using Servlets, EJBs, XML, and XSLT. He has also taught Java, HTML, and JavaScript at the University of Michigan Center for Corporate and Professional Development.
- AJAX World RIA Conference & Expo Kicks Off in New York City
- Ulitzer’s Amazing First 30 Days in Public Beta
- "Government IT Expo" to Highlight Cloud Computing and SOA
- Ulitzer vs. Ning - a Quick Review
- Improving the Efficiency of SOA-Based Applications
- Make Your Design Ideas Speak: Using UML in PowerBuilder Projects
- Ted Weissman and Lois Paul & Partners PR Firm
- SOA to Reduce Complexity?
- VMware Poaches CA Exec to Run Asia Pacific
- Cisco to Buy Tidal Software
- AJAX World RIA Conference & Expo Kicks Off in New York City
- Building the Right Project Team: The Rule of Five
- Ulitzer’s Amazing First 30 Days in Public Beta
- "Government IT Expo" to Highlight Cloud Computing and SOA
- DataDirect Data Integration Suite Features XQuery 4.0, XML Converters and Stylus Studio 2009
- Reducing Development Costs with SOA
- Macrovision White Paper Showcases Digital Entertainment Media
- Software AG Releases Tamino XML Server for SOA Interface
- Dajeil Launches Xerces/Xalan Hardware Accelerator for XML and SOA
- Ulitzer vs. Ning - a Quick Review
- AJAX World RIA Conference & Expo Kicks Off in New York City
- JSON vs XML - A Jason vs Freddie Sequel
- Processing XML with C# and .NET
- i-Technology Viewpoint: The Very Confused World of 3D and XML
- BPEL Processes and Human Workflow
- Open Source Database Special Feature: An Introduction to Berkeley DB XML
- "HP's Problem Ain't the SAP Install," Says Sun's Schwartz
- eXist - An Introduction To Open Source Native XML Database
- Digitizing the Planet: Google Earth vs MSN Virtual Earth vs MapQuest
- Product Review: Altova Enterprise Suite 2005





































