XSLT Transformations from Java and C++ with the DOM
In my book and in the two previous articles in this series I have frequently sung the praises of the World Wide Web Consortium's Document Object Model (DOM). Although several APIs have emerged as attractive alternatives to the DOM since it was first developed, it remains one of the most powerful and flexible means of processing XML. This article concludes the series by presenting the basics for using the DOM with another XML-related technology that's very useful to application developers: Extensible Stylesheet Language for Transformations (XSLT). We'll focus on how to perform XSLT transformations on DOM documents. This capability is very important in environments in which an application may be required to produce or consume XML documents that don't conform to the formats that it normally uses. For example, an order-entry application may be coded to accept XML purchase orders using a proprietary format, but customers may send orders formatted according to national or industry standards. Transforming input documents as a preprocessing step or output documents as a post-processing step, using XSLT in either case, can ease life in such heterogeneous environments.
As powerful as the DOM is, it's still being enhanced. One of the tasks still not addressed by even Level 3 of the DOM Recommendation is performing XSLT transformations on all or part of a DOM document. Fortunately, many major DOM implementations offer extensions that provide this functionality. Unfortunately, because these extensions are outside of the DOM recommendation, their implementations vary. We'll look at two implementations:
C++ with Microsoft's XML Core Services (MSXML)
Java with Java Architecture for XML Processing (JAXP) and with the Apache Foundation's Xalan XSLT processor
For this article we're concerned with how to perform XSLT transformations on DOM documents, and not with how to code the stylesheets used in XSLT transformations. However, we need an example, so we'll use a very basic "Hello World" transformation for both the C++ and Java programs. Listing 1 shows the source document.
Listing 1 Source document (HelloWorld.XML)
<?xml version="1.0" encoding="UTF-8"?> <Goodbye> you all </Goodbye>
We want to produce the result document in Listing 2.
Listing 2 Result document (ResultDocument.XML)
<?xml version="1.0" encoding="UTF-8"?> <HelloWorld> Howdy! </HelloWorld>
The source document is transformed into the result document using the very simple XSLT stylesheet in Listing 3.
Listing 3 Stylesheet (HelloWorld.XSL)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" sxmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!--This stylesheet produces the HelloWorld.xml result document from any source document--> <xsl:template match="/"> <HelloWorld>Howdy!</HelloWorld> </xsl:template> </xsl:stylesheet>
The stylesheet contains one template element that matches on the document root. It's a literal result template, containing the entire body of the result document. If you're familiar with XSLT, you'll note that any source document will produce the desired result when transformed with this stylesheet.
For more information on this particular transformation, see Chapter 10 of Using XML with Legacy Business Applications.
Although the C++ and Java implementations differ in the details and interfaces, the basic approach is the same in both:
Load the source document into a DOM document.
Load the stylesheet into a DOM document.
Create an empty DOM document for the result.
Perform the transformation, producing the result document.
Save the result document.
XSLT processing in both implementations is richer and more capable than that presented in this article. For example, either source or target can be objects other than DOM documents. But because many situations deal with a DOM-to-DOM transformation we'll focus on that task.