Making a Transformation Happen

You can transform documents in three ways:

  • On the server A server program, such as a Java servlet or a JavaServer Page (JSP), can use a stylesheet to transform a document automatically and serve it to the client. One such example is the XML Enabler, which is a servlet you'll find at the XML For Java Web site, www.alphaworks.ibm.com/tech/xml4j.

  • On the client A client program, such as a browser, can perform the transformation, reading in the stylesheet that you specify with the <?xml-stylesheet?> processing instruction. Internet Explorer can handle transformations this way, to some extent.

  • With a separate program Several standalone programs, usually based on Java, will perform XSLT transformations. I'll take a look at these programs in this chapter.

In this chapter, I'm going to use standalone programs to perform transformations because those programs offer by far the most complete implementations of XSLT. I'll also take a look at using XSLT in Internet Explorer and on the server.

On the Server

Here's an example showing how to use JavaServer Pages (JSP) to transform ch13_01.xml using ch13_02.xsl. JSP is not a skill you have to know in this book, but it provides some interesting examples of using Java, which we're already familiar with, and using XML on a Web server. Here's a JSP page that will perform the XSLT operation we want:

Listing ch13_03.jsp
 <%@ page import="javax.xml.transform.*, javax.xml.transform.stream.*, java.io.*" %> <%     try     {         TransformerFactory transformerfactory = TransformerFactory.newInstance();         Transformer transformer = transformerfactory.newTransformer(new StreamSource(new graphics/ccc.gif File             (application.getRealPath("/") + "ch13_02.xsl")));         transformer.transform(new StreamSource(new File(application.getRealPath("/") +             "ch13_01.xml")),         new StreamResult(new File(application.getRealPath("/") + "temp.html")));     }     catch(Exception e) {}     FileReader filereader = new FileReader(application.getRealPath("/") + "temp.html");     BufferedReader bufferedreader = new BufferedReader(filereader);     String instring;     while((instring = bufferedreader.readLine()) != null) { %>         <%= instring %> <%         }         filereader.close(); %> 

As we'll see in Chapter 18, "SOAP and RDF," the Tomcat server is the most popular one for use with JSP. You can see the results of this transformation using that server in Figure 13-1.

Figure 13-1. Performing an XSL transformation on the server.

graphics/13fig01.gif

You can see what has happened here: The names of the planets were stripped out of ch13_01.xml and displayed. That provides us with a starting point, and we'll take apart the XSL stylesheet used here in a few pages. We'll also see how to perform all kinds of fancy formatting operations on the data we extract from XML documents in this chapter.

There's another way to transform XML documents without a standalone program: You can use a client program such as a browser to transform documents.

Using Browsers to Transform XML Documents

To use ch13_01.xml with Internet Explorer, I have to make a few modifications. For example, I have to convert the type attribute in the <?xml-stylesheet?> processing instruction from "text/xml" to "text/xsl" in a new version of this document, ch13_04.xml:

Listing ch13_04.xml
 <?xml version="1.0"?>  <?xml-stylesheet type="text/xsl" href="ch13_02.xsl"?>  <PLANETS>     <PLANET>         <NAME>Mercury</NAME>         <MASS UNITS="(Earth = 1)">.0553</MASS>         <DAY UNITS="days">58.65</DAY>         <RADIUS UNITS="miles">1516</RADIUS>         <DENSITY UNITS="(Earth = 1)">.983</DENSITY>         <DISTANCE UNITS="million miles">43.4</DISTANCE><!--At perihelion-->     </PLANET>     <PLANET>         <NAME>Venus</NAME>         <MASS UNITS="(Earth = 1)">.815</MASS>         <DAY UNITS="days">116.75</DAY>         <RADIUS UNITS="miles">3716</RADIUS>         <DENSITY UNITS="(Earth = 1)">.943</DENSITY>         <DISTANCE UNITS="million miles">66.8</DISTANCE><!--At perihelion-->     </PLANET>     <PLANET>         <NAME>Earth</NAME>         <MASS UNITS="(Earth = 1)">1</MASS>         <DAY UNITS="days">1</DAY>         <RADIUS UNITS="miles">2107</RADIUS>         <DENSITY UNITS="(Earth = 1)">1</DENSITY>         <DISTANCE UNITS="million miles">128.4</DISTANCE><!--At perihelion-->     </PLANET> </PLANETS> 

Now you can navigate Internet Explorer to ch13_04.xml. You can see the results of this transformation in Figure 13-2.

Figure 13-2. Performing an XSL transformation in Internet Explorer.

graphics/13fig02.gif

Using Standalone Programs to Transform XML Documents

In earlier days, you had to download separate Java JAR files from various sources to perform XSLT transformations, but as of Java 1.4, Java includes everything you need. Here's an example showing how it works, ch13_05.java. You can use this Java application to transform ch13_01.xml, using ch13_02.xsl, into a new document called result.html:

 %java ch13_05 ch13_01.xml ch13_02.xsl result.html 

To write ch13_05.java, you start by using the TransformerFactory class to create a new object of the Transformer class, passing it the XSL stylesheet:

 import javax.xml.transform.*;  import javax.xml.transform.stream.*; import java.io.*; public class ch13_05 {     public static void main(String args[])     {         try         {  TransformerFactory transformerfactory = TransformerFactory.newInstance();   Transformer transformer = transformerfactory.newTransformer (new StreamSource( graphics/ccc.gif new File(args[1])));  .         .         .         }         .         .         .     } } 

You can see the methods of the TransformerFactory class in Table 13-1, and the methods of the Transformer class in Table 13-2.

Table 13-1. Methods of the TransformerFactory class
Method Does This
protected TransformerFactory() The default constructor
abstract Source getAssociatedStylesheet(Source source, String media, String title, String charset) Gets the stylesheet specification(s)
abstract Object getAttribute(String name) Returns specific attributes
abstract ErrorListener getErrorListener() Returns the error event handler for the TransformerFactory
abstract boolean getFeature(String name) Returns the value of a feature
abstract URIResolver getURIResolver() Gets the object that is used by default during the transformation to resolve URIs
static TransformerFactory newInstance() Obtains a new TransformerFactory object
abstract Templates newTemplates(Source source) Processes the Source into a Templates object (a compiled representation of the source)
abstract Transformer newTransformer() Creates a new Transformer object that copies of the source to the result
abstract Transformer newTransformer(Source source) Creates a new Transformer object that uses the Source for transformations
abstract void setAttribute(String name, Object value) Sets specific attributes
abstract void setErrorListener(ErrorListener listener) Sets the Java error event listener
abstract void setURIResolver(URIResolver resolver) Sets an object that is used by default during the transformation to resolve URIs
Table 13-2. Methods of the javax.xml.transform.Transformer Class
Method Does This
protected Transformer() The default constructor
abstract void clearParameters() Clears all the parameters that were set with setParameter
abstract ErrorListener getErrorListener() Returns the error event handler
abstract Properties getOutputProperties() Returns a copy of the output properties
abstract String getOutputProperty(String name) Returns the value of an output property
abstract Object getParameter(String name) Returns a parameter that was set with setParameter or setParameters
abstract URIResolver getURIResolver() Returns an object that will be used to resolve URIs
abstract void setErrorListener(ErrorListener listener) Sets the Java error event listener
abstract void setOutputProperties(Properties oformat) Sets the output properties
abstract void setOutputProperty(String name, String value) Sets an output property
abstract void setParameter(String name, Object value) Sets a parameter
abstract void setURIResolver(URIResolver resolver) Sets an object that will be used to resolve URIs
abstract void transform(Source xmlSource, Result outputTarget) Performs the transformation

To actually perform the transformation, you use the Transformer object's transform method, passing it the XML document to transform:

 import javax.xml.transform.*;  import javax.xml.transform.stream.*; import java.io.*; public class ch13_05 {     public static void main(String args[])     {         try         {             TransformerFactory transformerfactory = TransformerFactory.newInstance();             Transformer transformer = transformerfactory.newTransformer (new StreamSource( graphics/ccc.gif new File(args[1])));  transformer.transform(new StreamSource(new File(args[0])),   new StreamResult(new File(args[2])));  }         .         .         .     } } 

Note that files are handled with the StreamSource and StreamResult classes here, to fit the requirements of the Transformer class. You can see the methods of the StreamSource class in Table 13-3, and the methods of the StreamResult class in Table 13-4.

Table 13-3. Methods of the javax.xml.transform.stream.Stream Source Class
Method Does This
StreamSource() The default constructor
StreamSource(File f) Constructs a StreamSource from a File object
StreamSource(InputStream inputStream) Constructs a StreamSource from a byte stream
StreamSource(InputStream inputStream, String systemId) Constructs a StreamSource from a byte stream
StreamSource(Reader reader) Constructs a StreamSource from a character reader object
StreamSource(String systemId) Constructs a StreamSource from a URL
InputStream getInputStream() Gets the byte stream that was set with setByteStream
String getPublicId() Gets the public identifier that was set with setPublicId
Reader getReader() Gets the character stream that was set with setReader
String getSystemId() Gets the system identifier that was set with setSystemId
void setInputStream(InputStream inputStream) Sets the byte stream to be used as input
void setPublicId(String publicId) Sets the public identifier for this Source
void setReader(Reader reader) Sets the input to be a character reader
void setSystemId(File f) Sets the system ID from a File reference
void setSystemId(String systemId) Sets the system identifier for this Source
Table 13-4. Methods of the javax.xml.transform.stream.Stream Result Class
Method Does This
StreamResult() The default constructor
StreamResult(File f) Constructs a StreamResult from a File object
StreamResult(OutputStream outputStream) Constructs a StreamResult from a byte stream
StreamResult(String systemId) Constructs a StreamResult from a URL
StreamResult(Writer writer) Constructs a StreamResult from a character stream
OutputStream getOutputStream() Gets the byte stream that was set with setOutputStream
String getSystemId() Gets the system identifier that was set with setSystemId
Writer getWriter() Gets the character stream that was set with setWriter
void setOutputStream (OutputStream outputStream) Sets the ByteStream that is to be written to
void setSystemId(File f) Sets the system ID from a File reference
void setSystemId(String systemId) Sets the systemID that may be used in association with the byte or character stream
void setWriter(Writer writer) Sets the writer object that is used to get the result.

And that's all you need; here's the whole code:

Listing ch13_05.java
 import javax.xml.transform.*; import javax.xml.transform.stream.*; import java.io.*; public class ch13_05 {     public static void main(String args[])     {         try         {             TransformerFactory transformerfactory = TransformerFactory.newInstance();             Transformer transformer = transformerfactory.newTransformer (new StreamSource( graphics/ccc.gif new File(args[1])));             transformer.transform(new StreamSource(new File(args[0])),             new StreamResult(new File(args[2])));         }         catch(Exception e) {}     } } 

After compiling ch13_05.java into ch13_05.class, you can execute this command at the command prompt. This command assumes that all needed files are in the current directory, java ch13_05 ch13_01.xml ch13_02.xsl result.html . This produces result.html, which looks like this:

 <HTML>  <P>Mercury</P> <P>Venus</P> <P>Earth</P> </HTML> 

We've gotten an overview of XSL transformations now and seen them at work. It's time to see how to create XSLT stylesheets in detail.



Real World XML
Real World XML (2nd Edition)
ISBN: 0735712867
EAN: 2147483647
Year: 2005
Pages: 440
Authors: Steve Holzner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net