Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Creating Generic XSLT Transforms

By passing parameters to your XSLT documents, you can supply the extra information and simultaneously create transformations usable with many different XML documents.




Application Security Testing: An Integral Part of DevOps

uch of the focus of XSLT has been on its "stylesheet" capabilities—the ability to convert XML into some form of displayed HTML. However, XSLT is a functional language, one that takes an XML "state" and converts it into a different XML state—in essence, a form of black box that takes data in and spits different data out. You can use this to your advantage to turn XSLT scripts into client (or server side) methods that add significant power to your web development toolset, especially if your clients use Internet Explorer.

XSLT stylesheets are powerful and relatively easy to create for transforming specific XML documents, but it's not so apparent that they can also be generic, like a function call, so that they can handle a wide range of XML documents.

Parameters are an underused aspect of XSLT, but XSLT parameters can turn a specialized transformation script into a generalized method call. While an XML document contains the data on which the transformation will work, the data by itself is often not quite enough to accomplish a task. By passing parameters to your XSLT documents, you can supply the extra information and simultaneously create transformations usable with many different XML documents.

Basic Transformations
To clarify this, consider a simple XML document that consists of basic records (see Listing 1).

Suppose that you wanted to create a simple list that displayed the contents of the XML document shown in Listing 1. Listing 2 contains a very simple stylesheet to do just that. The stylesheet iterates through the records in the document, putting each in it's own <div> element, that contains the record id and the first and last names from each record .

Although the the sample displays the records in document order, the sample document records are ordered by user ID, simply because as each record is added to this list, the new user ID assigned is probably greater than the previous one. However, in many cases, a user ID provides very little ordering information; if the IDs were not generated sequentially but through some kind of algorithmic hash (or if the user ID were selected by the user), then the IDs would not be ordered. In other words, it would be preferable to be able to sort this information by some other key.

You could, of course, create one stylesheet for each kind of sorting. For example, the stylesheet in Listing 3 will sort automatically by first name:

Parameterized Transformations
Unfortunately, even with something as simple as the record set given above, you would need six different stylesheets to describe all the possible permutations -- firstname ascending, firstname descending, lastname ascending, ID ascending, and so forth. In other words, it makes more sense to attempt to parameterize the stylesheet, in this case with two parameters: $sortKey and $sortOrder. The $sortKey parameter specifies the name of the element or attribute to use as the sorting expression, while the $sortOrder parameter contains one of the values "ascending" or "descending".

The stylesheet in Listing 4 defines the two parameters $sortOrder and $sortKey at the global level—that is, outside of any specific template. Therefore, the two parameters are available to all the templates in the stylesheet. You can then sort using a single XSLT command:

<xsl:sort select="*[name(.)=$sortKey]|@*[name(.)=$sortKey]" order="{$sortOrder}"/>

The select attribute performs a generalized search, looking for either elements ("*[name(.)") or attributes ("@*[name(.)") that have the name of the sort key. By checking both, you can easily sort on attributes as well as elements, minimizing the need to have two such routines. You must escape the order attribute using the {} brackets, because its content is explicitly defined to be a string (in fact, it's a Name Token, but at least with most XSLT parsers, tokens are typically mapped to the string type).

is to convert six (and conceivably many more, if you were dealing with real records) stylesheets into one and turn a static stylesheet into a dynamic function that not only displays the records set but also uses the two parameters to control how that record set displays. You can use this subtle point to your advantage by encapsulating transformations in procedural functions.

Comment and Contribute








