advertisement
javaboutique
Search Tips
Articles  |   Tutorials  |   Reviews  |   Tools  |   by Category  |   by Date  |   by Name  |   Submit  |   Source  |   Forums  |  
javaboutique
Browse DevX


Partners & Affiliates











advertisement

Reviews : Java Books : Java and XSLT :


Title: Java and XSLT
ISBN: 0-596-00143-6, Order Number: 143-6
US Price: $39.95
© O'Reilly & Associates, Inc.

Input and Output

XSLT processors, like other XML tools, can read their input data from many different sources. In the most basic scenario, you will load a static stylesheet and XML document using the java.io.File class. More commonly, the XSLT stylesheet will come from a file, but the XML data will be generated dynamically as the result of a database query. In this case, it does not make sense to write the database query results to an XML file and then parse it into the XSLT processor. Instead, it is desirable to pipe the XML data directly into the processor using SAX or DOM. In fact, we will even see how to read nonXML data and transform it using XSLT.

System Identifiers, Files, and URLs

The simple examples presented earlier in this chapter introduced the concept of a system identifier. As mentioned before, system identifiers are nothing more than URIs and are used frequently by XML tools. For example, javax.xml.transform.Source, one of the key interfaces in JAXP, has the following API:

public interface Source {
    String getSystemId(  );
    void setSystemId(String systemId);
}

The second method, setSystemId( ), is crucial. By providing a URI to the Source, the XSLT processor can resolve URIs encountered in XSLT stylesheets. This allows XSLT code like this to work:

<xsl:import href="commonFooter.xslt"/>

When it comes to XSLT programming, you will use methods in java.io.File and java.net.URL to convert platform-specific file names into system IDs. These can then be used as parameters to any methods that expect a system ID as a parameter. For example, you would write the following code to convert a platform-specific filename into a system ID:

public static void main(String[] args) {
    // assume that the first command-line arg contains a file name
    // - on Windows, something like "C:\home\index.xml"
    // - on Unix, something like "/usr/home/index.xml"
    String fileName = args[0];
    File fileObject = new File(fileName);
    URL fileURL = fileObject.toURL(  );
    String systemID = fileURL.toExternalForm(  );

This code was written on several lines for clarity; it can be consolidated as follows:

String systemID = new File(fileName).toURL().toExternalForm(  );

Converting from a system identifier back to a filename or a File object can be accomplished with this code:

URL url = new URL(systemID);
String fileName = url.getFile(  );
File fileObject = new File(fileName);

And once again, this code can be condensed into a single line as follows:

File fileObject = new File((new URL(systemID)).getFile(  ));

JAXP I/O Design

The Source and Result interfaces in javax.xml.transform provide the basis for all transformation input and output in JAXP 1.1. Regardless of whether a stylesheet is obtained via a URI, filename, or InputStream, its data is fed into JAXP via an implementation of the Source interface. The output is then sent to an implementation of the Result interface. The implementations provided by JAXP are shown in Figure 5-3.

Figure 5-3. Source and Result interfaces

 

As you can see, JAXP is not particular about where it gets its data or sends its results. Remember that two instances of Source are always specified: one for the XML data and another for the XSLT stylesheet.

JAXP Stream I/O

As shown in Figure 5-3, StreamSource is one of the implementations of the Source interface. In addition to the system identifiers that Source provides, StreamSource allows input to be obtained from a File, an InputStream, or a Reader. The SimpleJaxp class in Example 5-3 showed how to use StreamSource to read from a File object. There are also four constructors that allow you to construct a StreamSource from either an InputStream or Reader. The complete list of constructors is shown here:

public StreamSource(  )
public StreamSource(File f)
public StreamSource(String systemId)
public StreamSource(InputStream byteStream)
public StreamSource(InputStream byteStream, String systemId)
public StreamSource(Reader characterStream)
public StreamSource(Reader characterStream, String systemId)

For the constructors that take InputStream and Reader as arguments, the first argument provides either the XML data or the XSLT stylesheet. The second argument, if present, is used to resolve relative URI references in the document. As mentioned before, your XSLT stylesheet may include the following code:

<xsl:import href="commonFooter.xslt"/>

By providing a system identifier as a parameter to the StreamSource, you are telling the XSLT processor where to look for commonFooter.xslt. Without this parameter, you may encounter an error when the processor cannot resolve this URI. The simple fix is to call the setSystemId( ) method as follows:

// construct a Source that reads from an InputStream
Source mySrc = new StreamSource(anInputStream);
// specify a system ID (a String) so the Source can resolve
// relative URLs that are encountered in XSLT stylesheets
mySrc.setSystemId(aSystemId);

The documentation for StreamSource also advises that InputStream is preferred to Reader because this allows the processor to properly handle the character encoding as specified in the XML declaration.

StreamResult is similar in functionality to StreamSource, although it is not necessary to resolve relative URIs. The available constructors are as follows:

public StreamResult(  )
public StreamResult(File f)
public StreamResult(String systemId)
public StreamResult(OutputStream byteStream)
public StreamResult(Writer characterStream)

Let's look at some of the other options for StreamSource and StreamResult. Example 5-4 is a modification of the SimpleJaxp program that was presented earlier. It downloads the XML specification from the W3C web site and stores it in a temporary file on your local disk. To download the file, construct a StreamSource with a system identifier as a parameter. The stylesheet is a simple one that merely performs an identity transformation, copying the unmodified XML data to the result tree. The result is then sent to a StreamResult using its File constructor.

Example 5-4: Streams.java

package chap5;
 
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
 
/**
 * A simple demo of JAXP 1.1 StreamSource and StreamResult. This 
 * program downloads the XML specification from the W3C and prints
 * it to a temporary file.
 */
public class Streams {
 
    // an identity copy stylesheet
    private static final String IDENTITY_XSLT =
	 "<xsl:stylesheet xmlns:xsl=
		'http://www.w3.org/1999/XSL/Transform'"
	 + " version='1.0'>"
	 + "<xsl:template match='/'>
	<xsl:copy-of select='.'/>"
	 + "</xsl:template></xsl:stylesheet>";
 
    // the XML spec in XML format
    // (using an HTTP URL rather than a file URL)
    private static String xmlSystemId =
	"http://www.w3.org/TR/2000/REC-xml-20001006.xml";
 
    public static void main(String[] args) throws IOException,
            TransformerException {
 
        // show how to read from a system identifier and a Reader
        Source xmlSource = new StreamSource(xmlSystemId);
        Source xsltSource = new StreamSource(
                new StringReader(IDENTITY_XSLT));
 
        // send the result to a file
        File resultFile = File.createTempFile("Streams", ".xml");
        Result result = new StreamResult(resultFile);
 
        System.out.println("Results will go to: "
                + resultFile.getAbsolutePath(  ));
 
        // get the factory
        TransformerFactory transFact = 
			TransformerFactory.newInstance(  );
 
        // get a transformer for this particular stylesheet
        Transformer trans = 
		transFact.newTransformer(xsltSource);
 
        // do the transformation
        trans.transform(xmlSource, result);
    }
}
Note: Color coded lines have been broken for display purposes.

The "identity copy" stylesheet simply matches "/", which is the document itself. It then uses <xsl:copy-of select='.'/> to select the document and copy it to the result tree. In this case, we coded our own stylesheet. You can also omit the XSLT stylesheet altogether as follows:

// construct a Transformer without any XSLT stylesheet
Transformer trans = transFact.newTransformer(  );

In this case, the processor will provide its own stylesheet and do the same thing that our example does. This is useful when you need to use JAXP to convert a DOM tree to XML text for debugging purposes because the default Transformer will simply copy the XML data without any transformation.

How to Add Java Applets to Your Site

New on the Java Boutique:

New Review:

Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling API boasts simplicity, ease-of-integration, a well-rounded feature set, and it's free!

New Applet:

Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA sequences into three useful formats.

Elsewhere on internet.com:

WebDeveloper Java
Lots of Java information on webdeveloper.com

WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.

ScriptSearch Java
Hundreds of free Java code files to download.

jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.

 Avaya Developer Showcase
 MSDN Spotlight
 PHP for Windows Showcase
XML error: undefined entity at line 34
advertisement
Receive Articles via our XML/RSS feed
Receive Articles via our XML/RSS feed

JavaBytes
Internet Cyclone
This powerful, easy-to-use, internet optimizer is for Windows 95, 98, ME, NT, 2000 and XP. It's designed to automatically optimize your Windows settings, boosting your Internet connection up to 200%.

IBM Brings Developers Into the Cloud
Apache at 10: You Can't Buy Us
Microsoft's CodePlex Foundation Moving Forward
Apple Claims 100,000 Apps, Google Analyzes Them
Nokia Latest to Play Opera Mobile 10 Browser
PayPal Opens Up Payment Platform to Devs
Ubuntu Linux 9.10 'Karmic Koala' Starts Its Climb
IBM Links Rational Developer Tools, Tivoli Apps
Libraries Give Vista Apps a Windows 7 Look
Ubuntu: The 'Default Alternative' to Windows?

Delivering Web-based Embedded Fonts in CSS 3
Adobe Helps PHP Developers Create Rich Internet Applications
Java Developers Finding a Home at Adobe Flex
Virtualization Delivers a Dynamic Infrastructure
Consuming XML Web Services in iPhone Applications
Build a More Agile Business with IBM
POJO-Based Solutions for LDAP Access: One Good, One Better
IBM Offers Enhanced Measurement and Management for Energy Usage
IBM Helps Transformation to an Information-Based Enterprise
Top Five Touch UI-Related Design Guidelines

Advertising Info  |   Member Services  |   Contact Us  |   Help  |   Feedback  |   Site Map  |   Network Map  |   About

internet.commediabistro.comJusttechjobs.comGraphics.com

Search:

WebMediaBrands Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Shopping | E-mail Offers | Freelance Jobs