Combining XSL Transformation and Applications
- Transformation Methodologies
- Transforming Data
- Templates and Parameters
- Transformations and SAX
- Programming Within a Style Sheet
- Summary
- Review Questions
- Programming Exercises
You will learn about the following in this chapter:
Transforming documents
Transformation sources, results, and style sheets
Using SAX with XSL transformations
Extension elements and functions
In the grand scheme of things, there are plenty of reasons you might want to use XSL to transform data. The most common revolves around XML's ability to separate content from presentation; XSL transformations (XSLT) allow you to have a single XML file for your content, but provide different presentations for Web pages, paper reports, cell phones, and so on.
XSL transformations can also be used to massage data into a different form. For example, you could build an application that transforms XML from one format to another using a style sheet, then let users create the style sheet. In this way, they can control the final output and you don't have to alter the application.
XSL transformations can be carried out on the client sidein a browser, for examplebut they are most useful when they're performed as part of an application.
In this chapter, we'll create applications that perform transformations using the style sheets created in Chapter 9, "Extensible Stylesheet Language Transformations (XSLT)." We'll look at the different sources and outputs, as well as different ways to make transformations more efficient and to control them programmatically, such as by choosing a style sheet based on the XML file, or adding parameters. We'll also look at the relationship between SAX and transformations.
Finally, we'll go in the other direction, adding programming to a style sheet itself, creating extension functions and elements using first JavaScript, then Java.
Transformation Methodologies
Before we actually start programming, let's consider several different ways to look at performing transformations. The XSLT Recommendation provides no guidance on how the actual transformation is to be implemented, only on what it should do when it is implemented.
Getting Ready
Before starting the examples in this chapter, be sure that you have an XSL transformation engine installed. (If you did the examples in Chapter 9, you've likely taken care of this already.) You may also need to consult your documentation for specific classnames.
The Java examples in this chapter use the implementation of XSLT that comes with Java 1.4.
Transformation API for XML (TrAX)
Currently, the most common way to perform a transformation is to use the Transformation API for XML (TrAX). The TrAX methodology was originally intended for Java programmers, but its utility is evidenced by the fact that it has been adopted by implementers in most other languages. Using TrAX involves three steps:
-
Create a transformer factory. This allows you to choose an implementation other than the standard one for the factory, if necessary.
-
Create the transformer, giving it a style sheet as input. The transformer is particular to the style sheet with which it was created. Any file it transforms will use that style sheet.
-
Use the transform() method of the Transformer object (or something similar) to transform a particular supplied source into a particular supplied result. For example:
transformerObj.transform(source, result);
Language-Specific Issues
In some languages and implementations, such as C++ and Visual Basic .NET, the situation is slightly altered. In these languages, the source object itself performs the transformation, using the style sheet and result as inputs. The following sections show some examples.
C++ and Visual Basic .NET
MSXML 4.0 provides two methods to invoke transformations from C++ and Visual Basic .NET. The only difference between the two methods is the way the transformed data is returned. To receive the data as a BSTR, use transformNode();. To receive the data as an IXMLDOMDocument or IStream object, use transformNodeToObject(), as shown in these C++ examples:
// This call will produce a string for output bstrXMLStr = pXMLDoc->transformNode(pXSLTDoc); // This call will produce an object for output pXMLDoc->transformNodeToObject(pXSLTDoc, vOutput);
Implementation Note
The Apache Project also provides a C++ version of the Xalan transformation engine, which uses a TrAX-like means for transforming documents much like the Java version, rather than the object-based method used by MSXML. You can find more information at http://xml.apache.org/xalan-c/index.html.
PHP
Sablotron, produced by the Ginger Alliance (http://www.gingerall.cz), is the most mature XSLT processor available for use directly by PHP. Using XSLT in PHP with Sablotron is quite straightforward and relies on the TrAX methodology shown earlier in the Java example, though I should note that many of the features of TrAX are not supported. Building Sablotron for use in PHP is not at all easy, however; both the PHP and Sablotron source code must be patched, and PHP must be built with options that vary depending on whether you plan to use JavaScript extensions in your style sheets. In other words, if you can find a prebuilt PHP+Sablotron package for your operating system or distribution, use it.
Perl
There are three major XSLT packages for Perl in active use and development: XML::Sablotron, based on the Sablotron library produced by the Ginger Alliance (http://www.gingerall.cz); XML::LibXSLT, based on the GNOME XSLT library (http://xmlsoft.org/XSLT); and XML::Xalan, based on the Xalan XSLT processor, a part of the Apache project (http://xml.apache.org/xalan-c). Of these, XML::Sablotron is the most mature and widely packaged, so we'll use XML::Sablotron for our Perl examples. Though based on the same library as PHP's XSLT functions, XML::Sablotron exposes much more of the underlying library's abilities than does PHP's library. Unlike Sablotron for PHP, no patching is required to build Sablotron for use by Perl. However, if you plan to use JavaScript extensions in your style sheets, you must first install the Mozilla JavaScript library and build XML::Sablotron with JavaScript support. Once you've installed it, the usage patterns vary from Java, but not by much.
Transforming Streams
In the case of a SAX stream, there is no object to transform, but this doesn't mean that SAX streams can't use XSLT. In such cases, the transformer acts like the ContentHandler, making changes as it goes along. In this way, transformations can even be chained together, with the results of one transformation serving as the source of another, just as SAX streams can be chained together.
In this chapter, we'll examine the transformation of both objects and streams in the appropriate languages.