You will learn about the following in this chapter:
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.
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.
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:
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);
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.
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.