Retired Content

This content is not examinable so please don't study it if you come across it!

It is merely a place for me to put perfectly good examples and code that isn't currently in the module syllabus.

Hibernate  (Retired)

One Class to Two Tables    (Retired)

Let us consider a scenario where our application defines a single class, but the database maintains the corresponding information in two seperate tables.  This process is relatively straightforward.  To map one Java class to two database tables we define the first table mapping as we normally would and then specify the name of the second table your class uses with the @SecondaryTable annotation.  Then when you get to a field that should be stored in the second table, you just mention the second table's name in the @Column annotation.

Let's take an example.  Let us expand on our Customer object and add a few fields to represent a billing address: street, city and postcode.  We wish our mapping to look like the following:

Hibernate One Class to Two Tables 

You will have noticed that I have renamed the class to Customer2 and the corresponding table names will be calledCustomer_David456 and Billing_David456.  While we could have left the class and the first table with the same names as before, it would overwrite our previous examples.  To avoid this situation, we have simply given them new names. 

Let us take a look at our annotated file which will perform this mapping to two tables.


import javax.persistence.*;

 * Our Customer JavaBean with Annotations (POJO)
 * @author David Molloy
 * Don't forget to change the table names to your own values!
@Table (name="Customer_David456")
public class Customer2 {
	private int id;
	private String username;
	private String password;
	private String firstname;
	private String surname;
	private String email;
	private String street;
	private String city;
	private String postcode;
	public Customer2(int id, String username, String password, String firstname, String surname, String email, 
             String street, String city, String postcode) {
		super(); = id;
		this.username = username;
		this.password = password;
		this.firstname = firstname;
		this.surname = surname; = email;
		this.street = street; = city;
		this.postcode = postcode;
	public Customer2() {
	public int getId() {
		return id;
	public void setId(int id) { = id;
	public String getUsername() {
		return username;
	public void setUsername(String username) {
		this.username = username;
	public String getPassword() {
		return password;
	public void setPassword(String password) {
		this.password = password;
	public String getFirstname() {
		return firstname;
	public void setFirstname(String firstname) {
		this.firstname = firstname;
	public String getSurname() {
		return surname;
	public void setSurname(String surname) {
		this.surname = surname;
	public String getEmail() {
		return email;
	public void setEmail(String email) { = email;
	public String getStreet() {
		return street;

	public void setStreet(String street) {
		this.street = street;

	public String getCity() {
		return city;

	public void setCity(String city) { = city;

	public String getPostcode() {
		return postcode;

	public void setPostcode(String postcode) {
		this.postcode = postcode;

There are a few minor differences between Customer2 and the original Customer.  Firstly, the new properties have been added to the bean, the appropriate getter and setter methods and a few extra annotations.

Specifically, the new annotations are: 


at the top of the class where we define the @Entity and:


placed above each of the getter() methods for the fields we have stored in the second database table.

So let's write a quick application which will demonstrate this annotated bean in action:

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Example;

 * Example Class to show Hibernate CRUD Operations
 * @author David Molloy
public class OneToTwoExample {
	 * Main method which runs first... we can modify the methods 
	 * that are called for different results
	public static void main(String[] args) {
		Session session = HibernateUtil.beginTransaction();
		// Comment this next line if you want to stop dropping and recreating tables every execution
		// First create some customer entities using a method we have created
		CreateCustomer2(session, "Michael", "Reilly", "reillym", "password", 
				"", "123 Fake Street", "Faketown", "Fake123");
		showUniqueCustomer2ByUsername(session, "reillym");  // Display all of our Customer entities
	 * This method creates a new Customer entity in the database using the
	 * fields provided as arguments
	public static void CreateCustomer2(Session session, String firstname, String surname, 
			String username, String password, String email, String street, String city, String postcode) {
		System.out.println("Creating new Customer2 with Billing");
		Customer2 customer2 = new Customer2();
		System.out.println("Customer2 Saved!");
	 * This method will print out the name of the Customer2 who matches a username
	 * This will be a unique single user as we will assume a unique username
	private static void showUniqueCustomer2ByUsername(Session session, String username) {
		Customer2 c = new Customer2();
		Example example = Example.create(c);
		Criteria criteria = session.createCriteria(Customer2.class);
		Customer2 customer2 = (Customer2) criteria.uniqueResult();
		System.out.println("\nUnique customer matchining username " + username +
				" is " + customer2.getFirstname() + " " + customer2.getSurname());

As a brief explanation of the above:

  • main: The main method gets the Hibernate session, recreates our database structure and calls in turn the next two methods.  Finally, it commits and closes the session.
  • CreateCustomer2: This method simply populates our Customer2 object with all of the properties associated with it, including the three new properties: street, city and postcode.  It saves the Customer2 entity into the database  (using the two tables).
  • showUniqueCustomer2ByUsername: Very similar to the almost identically named method in 'CriteriaExample' this method uses the Criteria API to retrieve the Customer2 that matches the passed username. 

There is one other step which needs to be added.  As we are using a seperate JavaBean called 'Customer2' this needs to be added to the list of JavaBeans for which Hibernate will manage persistence.  To do this you need to add the line:  config.addAnnotatedClass(Customer2.class);  to the file in the appropriate place.   If we omit to do this, the JavaBean will still be technically error free, but Hibernate will not perform any database operations.

The output from this application should look something like the following:

16:08:10,906 DEBUG SchemaExport:377 - drop table Billing_David456 cascade constraints
drop table Customer_David123 cascade constraints
16:08:10,984 DEBUG SchemaExport:377 - drop table Customer_David123 cascade constraints
drop table Customer_David456 cascade constraints
16:08:11,000 DEBUG SchemaExport:377 - drop table Customer_David456 cascade constraints
drop sequence hibernate_sequence
16:08:11,031 DEBUG SchemaExport:377 - drop sequence hibernate_sequence
create table Billing_David456 (city varchar2(255 char), postcode varchar2(255 char), street varchar2(255 char), id number(10,0) 
not null, primary key (id))
16:08:11,062 DEBUG SchemaExport:377 - create table Billing_David456 (city varchar2(255 char), postcode varchar2(255 char), 
street varchar2(255 char), id number(10,0) not null, primary key (id))
create table Customer_David123 (id number(10,0) not null, email varchar2(255 char), firstname varchar2(255 char), 
password varchar2(255 char), surname varchar2(255 char), username varchar2(255 char), primary key (id))
16:08:11,109 DEBUG SchemaExport:377 - create table Customer_David123 (id number(10,0) not null, email varchar2(255 char), 
firstname varchar2(255 char), password varchar2(255 char), surname varchar2(255 char), 
username varchar2(255 char), primary key (id))
create table Customer_David456 (id number(10,0) not null, email varchar2(255 char), firstname varchar2(255 char), 
password varchar2(255 char), surname varchar2(255 char), username varchar2(255 char), primary key (id))
16:08:11,125 DEBUG SchemaExport:377 - create table Customer_David456 (id number(10,0) not null, email varchar2(255 char), 
firstname varchar2(255 char), password varchar2(255 char), surname varchar2(255 char), 
username varchar2(255 char), primary key (id))
alter table Billing_David456 add constraint FKCEE3086588C8C38E foreign key (id) references Customer_David456
16:08:11,140 DEBUG SchemaExport:377 - alter table Billing_David456 add constraint FKCEE3086588C8C38E 
foreign key (id) references Customer_David456
create sequence hibernate_sequence
16:08:11,140 DEBUG SchemaExport:377 - create sequence hibernate_sequence
16:08:11,156  INFO SchemaExport:268 - schema export complete
16:08:11,156  INFO DriverManagerConnectionProvider:170 - cleaning up connection pool: jdbc:oracle:thin:@
Creating new Customer2 with Billing
Hibernate: select hibernate_sequence.nextval from dual
Customer2 Saved!
Hibernate: insert into Customer_David456 (email, firstname, password, surname, username, id) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into Billing_David456 (city, postcode, street, id) values (?, ?, ?, ?)
Hibernate: select as id1_0_, as email1_0_, this_.firstname as firstname1_0_, this_.password as password1_0_, 
this_.surname as surname1_0_, this_.username as username1_0_, as city2_0_, this_1_.postcode as postcode2_0_, 
this_1_.street as street2_0_ from Customer_David456 this_ left outer join Billing_David456 this_1_ 
on where (this_.username=?)

Unique customer matchining username reillym is Michael Reilly

Looking at the output, there are a few points of note:

  • Even though we aren't using Customers_David123 it is dropped and recreated.  This is simply because the HibernateUtil.recreateDatabase() method will recreate the database for all beans it has been told to manage.
  • Two tables are created (as we would expect) and an appropriate foreign key relationship is set up because the two tables.  The id column of the Billing_David456 table is the foreign key referencing Customer_David456.
  • The select statement performs the necessary join automatically for us, combining the two tables using the matching columns''.  

JDBC Drivers

Individual databases are accessed via a specific JDBC driver that implements the java.sql.Driver inferface. JDBC drivers are available for most database platforms and from a number of different vendors. There are four different driver types as follows:

  1. Type 1: JDBC-ODBC Bridge Driver - These drivers show a JDBC face but call into an ODBC driver, which itself is normally implemented on top of a native driver written in C, C++ or another language. The actual communication with the database occurs through the ODBC drivers.

  2. Type 2: Native-API Partly Java Driver - These drivers are implemented directly against the underlying native driver, eliminating the ODBC layer. Native drivers are still required. Typically, type 2 drivers wrap a thin layer of Java around database-specific native code libraries. As an example, with Oracle, the native code libraries are typically based on the OCI (Oracle Call Interface) libraries, which were originally designed for C/C++ programmers. Because Type 2 Drivers are implemented using native code, in some cases they can have better performance than their all-Java counterparts.

  3. Type 3: Net-Protocol All-Java Driver - Type 3 drivers communicate via a generic network protocol to a piece of custom middleware. The client translates the database requests to a standard request format that is independent of any DBMS requests. The receiving middleware component parses this request and passes it to the specific DBMS. The middleware component might use any type of driver to provide the actual database access. With type 3 drivers, many clients can connect to many databases, and this type of driver is the most flexible one. These drivers are written entirely in Java.

  4. Type 4: Native-Protocol/All-Java Driver - Purely Java based, type 4 drivers or thin drivers translate the database requests into a specific DBMS-understandable format. There is a direct call on the DBMS from the client and hence are no intervening layers. Since type 4 drivers are written completely in Java, they can run virtually unchanged on any platform.

The following diagram shows the JDBC architecture options using the different driver types:

Figure 7.4. JDBC Driver Architecture

Java API for XML Processing (JAXP)

When dealing with XML programmatically, one of the first things you have to do is take an XML document and parse it. Parsing is the process of dissecting a body of text into its individual component pieces. For example, if that body of text is a paragraph, parsing would break the paragraph into sentences. It would then break a sentence down to a subject and predicate. In turn, the subject and predicate would then be broken down into their components like nouns, verbs and adjectives. In the same way, we use parsing to obtain our data and meta-data from our XML documents.

The Java API for XML Processing (JAXP) is for processing XML data using applications written in the Java programming language. JAXP uses the parser standards SAX (Simple API for XML Parsing) and DOM (Document Object Model) so that you can choose to parse your data as a stream of events or to build an object representation of it. JAXP also supports the XSLT (XML Stylesheet Language Transformations) standard, giving you control over the presentation of data and enabling you to convert the data to other XML documents or to other formats, such as HTML.

The main JAXP APIs are defined in the javax.xml.parsers package. That package contains two vendor-independent factory classes:

  • SAXParserFactory - gives you a SAXParser (used for SAX)

  • DocumentBuilderFactory - gives you a DocumentBuilder, which in turn creates a DOM-compliant Document object (used for DOM)

Simple API for XML (SAX)

The "Simple API for XML" (SAX) is the event-driven mechanism that does element-by-element processing. For server-side and high-performance applications it is typically SAX which is used. When it comes to fast, efficient reading of XML data, SAX is hard to beat. It requires little memory, because it does not construct an internal representation (tree structure) of the XML data. Instead, it simply sends data to the application as it is read - your application can then do whatever it wants to do with the data it sees.  

SAX is an event driven process to identify the elements as the parser reads them. It then informs the application of events, such as the start and end of elements. In effect, the SAX API acts like a serial I/O stream - you see the data as it streams in, but you can't go back to an earlier position or leap ahead to a different position. In general it works well when you simply want to read data and have the application act on it.  As the data is parsed the various element events call handling methods such as startDocument, endDocument, startElement, endElement and characters.

Document Object Model (DOM)

The Document Object Model (DOM) API is generally an easier API to use. It provides a relatively familiar tree structure of objects. The DOM API is ideal for interactive applications because the entire object model is present in memory, where it can be accessed and manipulated by the user. On the negative side, constructing the DOM requires reading the entire XML structure and holding the object tree in memory, so it is much more CPU and memory intensive. For that reason, the SAX API will tend to be preferred for server-side applications and data filters that do not require an in-memory representation of the data. However, when you need to modify an XML structure - especially when you need to modify it interactively, an in-memory structure like the DOM may make more sense. While DOM provides many powerful capabilities for large-scale documents (like books), it also requires a lot of complex coding.

Figure 3.4. DOM Tree Structure representing XML



  • Serial, event-driven mechanism

  • Fast, efficient

  • Requires little memory

  • Handles data when encountered

  • Preferred for server-side read applications


  • Provides a tree structure of objects

  • Powerful capabilities/Complex Coding

  • Higher memory/CPU requirements

  • Entire XML structure read in first
  • Typically used for interactive modification of XML

In previous years, more detail was looked at in relation to both SAX and DOM.  However, due to the adding of other material, something had to give... so this is all we will look at in relation to SAX and DOM.  If you are interested, you can find the material from a previous module at:

Extensible StyleSheet Language (XSL)


The eXtensible Stylesheet Language (XSL) is the language that describes how XML documents should be displayed. XSL was developed by the W3C Working Group and consists of three parts:

  • XSL Transformations (XSLT) - XSLT is the language that specifies the conversion of a document from one format to another, where XSL defines the means of that specification. The syntax used within XSLT is generally concerned with textual transformations that do not result in binary data output. For example, XSLT is instrumental is generating HTML or WML (Wireless Markup Language) from an XML document.

  • XSL Formatting Objects (XSL-FO) - Formatting objects are used heavily when converting textual XML data into binary formats such as PDF files, images or document formats such as Microsoft Word. For example, XSL-FOs are used in generating the PDF version of these notes, whereas XSLT is used for the HTML version. This is the largest subcomponent of XSL and gives mechanisms for describing font sizes, page layouts and how information flows from one page to another. This subcomponent is *not* covered by JAXP, nor described further in this module.

  • XPath - XSLT is a language that lets you specify what sorts of things to do when a particular element is encountered. But to write a program for different parts of an XML data structure, you need to be able to specify the part of the structure you are talking about at any given time. XPath is that specification language. It is an addressing mechanism that lets you specify a path to an element, so, for example, <name><title> can be distinguished from <qualification><title>. That way, we can describe different kinds of translations for the different <title> elements.

Style Sheets

A stylesheet is an XML document contained within a stylesheet element. The style sheet transforms the input/source document's tree into a new structure. As usual, Style Sheets are probably best explaining by providing an example. First let us consider the XML data we will work on - this is a slightly modified version of the previous personnel.xml file. We have added one extra line, which makes reference to the XSL Style Sheet we wish to use.

<?xml version='1.0'?> <?xml-stylesheet type='text/xsl' href='xslexample1.xsl'?> <personnel> <person> <firstname>David</firstname> <lastname>Molloy</lastname> </person> <person> <firstname>John Peter</firstname> <lastname>Smith</lastname> </person> <person> <firstname>Jane</firstname> <lastname>Grogan</lastname> </person> </personnel>

So, now consider the following stylesheet:

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="" version="1.0"> <xsl:template match="/"> <HTML> <BODY bgcolor="wheat"> <xsl:for-each select="personnel/person"> <BR/><H2>Employee</H2> <B>Firstname: </B><xsl:value-of select="firstname" /><BR/> <B>Lastname: </B><xsl:value-of select="lastname" /><BR/><BR/> </xsl:for-each> </BODY> </HTML> </xsl:template> </xsl:stylesheet>

As we previously stated, the stylesheet is an XML document contained within a stylesheet element. An xsl:stylesheet element must have a version attribute, indicating which version of XSLT that the style sheet requires. The xsl:stylesheet element, which is the root of the XSL Stylesheet XML tree, can have eleven child elements. In this module, we will not be describing all of these elements, but will be only covering a small number. One of these is the xsl:template element. This element is the most important top-level element in an XSL stylesheet. While all other elements add to a stylesheet, xsl:template is its core. xsl:template defines the template construction rules for translating one XML document to another format. XSL utilizes templates to define how to output XML elements. Each template contains match patterns that determine where the template applies. In this example, the template attribute match="/" associates that template to the root of the source document.

The <xsl:for-each select="personnel/person"> line and corresponding closing tag is our equivalent to a Java 'for' loop within XSL. In english, for every <person> element within <personnel> we output the HTML shown within the loop. Within that loop, reference is made to <xsl:value-of select="firstname" /> which simply inserts the value of the <firstname> element encountered. Note: If you want to get the text value of attributes, you should use an @ symbol in front of the name. For example: <xsl:value-of select="@attributename" />. This is not used within this example, but is used in the later example for the account 'type'.

As can be seen, our XSL document in this example, is a mixture of HTML and specific XSL elements.

In this section on XSL we are merely touching on the very basics of XSL. It is quite a complicated yet very powerful language, yet for the purpose of this module, the information provided in the notes is sufficient.

Client-side Transformations

Microsoft Internet Explorer 5.0 and upwards actually goes a long way towards implementing client-side support for XML and XSL. However, as with any bleeding-edge product, MSIE 5.0 shipped before the standards had solidified, and unfortunately, much has changed. In addition MSIE 5.0 added to XML in many non-standard ways. While browser differences have not been completely ironed out in later versions of Internet Explorer, it is sufficient for use for this example.  The following examples should function in recent versions of the following browsers (according to my testing!):

  • Chrome
  • Internet Explorer
  • Opera
  • Firefox
  • Safari

Figure 3.5. Client-Side vs Server-Side XSL Transformations

So now, all that remains is the see the client-side transformation in action. It is for this reason that I left the link blank under the example above. In IE5.0+ if you type a URL which references an XML document and that document in turn references an XSL stylesheet, IE will perform a client-side transformation automatically and display the HTML.

View the output in your browser: xslexample1.xml

In case you wish to create the XML file in your own directory, here is the XSL file you will also require: xslexample1.xsl

Note: If you try to use the above link using Netscape 4.7 or other non-XML supporting browsers, it will not be able to open the file without a third-party application. For the benefit of students who do not have Internet Explorer I provide the output of the above link as a screenshot viewed within IE5.0.

Figure 3.6. Internet Explorer Client-Side Transformation Output

Server-side Transformation

Referencing stylesheets from within XML documents is not the optimal method for transformations. This method depends on the widespread adoption of browsers supporting the XSL recommendation--something you cannot count on if you are a web developer. By using the server's ability to detect the client's browser, you can have one XML file and apply a specific stylesheet based on the client profile. This allows the XML document on the server to be transformed using a specific stylesheet and then sent to the client as pure XHTML or other formats. Using the server's power to transform will also benefit slow connections and small devices. The benefits of server-side processing easily outweigh those of client-side processing. This fact should make server-side processing the preferred method for transformations.

One obvious way of handling the transformation on the server-side is to use a stylesheet processor such as Xalan. Xalan provides high-performance XSLT stylesheet processing. Xalan fully implements the W3C XSLT and XPath recommendations and is available in Java and C++. So show Xalan in action, we can use it at the command line:

java -classpath .;xalan.jar org.apache.xalan.xslt.Process -IN xslexample1.xml -XSL xslexample1.xsl -OUT xslexample1.html

After this command is executed, a file called 'xslexample1.html' will be generated in the same directory. Hence, one obvious way of performing server-side transformations is to use a Xalan transformation at command line on the server and make the HTML document available. The primary advantage of taking such an option is that only the HTML is transported to the client browser and no transformation is expected to be performed there. This means that the XML output (in this case HTML) can be viewed from within non-supporting browsers such as Netscape 4.7, just as easily as within Internet Explorer 5.0. This server-side transformation also removes the concerns about lack of standards compliance from within the seperate browsers, even those who claim to support XML client-side transformations.

Note: In order to get this example to work, you will need to have downloaded 'xalan.jar' which can come as part of the full distribution of Xalan, downloadable from the Apache XML Project. Alternatively, you can download the file itself (local JAR) which will allow you to get the example to run.

XSL Example 2

Question: Take this XML document and convert it to a similar HTML document as the one that is shown.

<?xml version="1.0" encoding="UTF-16"?> <?xml-stylesheet type='text/xsl' href='xslcustomers.xsl'?> <customers> <customer> <name> <firstname>David</firstname> <lastname>Molloy</lastname> <title>Mr.</title> </name> <account type="Cashsave"> <date>02/02/89</date> <balance>1202.80</balance> </account> <account type="Current"> <date>13/09/98</date> <balance>505.60</balance> </account> </customer> <customer> <name> <firstname>Maeve</firstname> <lastname>O'Reilly</lastname> <title>Ms.</title> </name> <account type="SSIA"> <date>01/03/02</date> <balance>5500.34</balance> </account> </customer> </customers>

Source: xslcustomers.xml

Expected HTML Output: xslcustomers.html 

Once you have created your stylesheet, perform a client-side transformation within Internet Explorer (if you have it) and a manual transformation using Xalan.


The following is the stylesheet that I created - it works similarly to the introduction example in the notes, except it has two 'for' loops instead of just one. Because there can be multiple 'account's per 'customer' we need the first loop to enumerate our customers and a second internal loop to enumerate through the individual accounts.

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="" version="1.0"> <xsl:template match="/customers"> <HTML> <BODY bgcolor="#777777"> <xsl:for-each select="customer"> <BR/><H2>Customer Name: <xsl:value-of select="name/firstname" /> <xsl:text> </xsl:text> <xsl:value-of select="name/lastname" /></H2> <!-- Now we wish to print out the account details --> <xsl:for-each select="account"> Account Type: <xsl:value-of select="@type" /> <BR />Balance: <xsl:value-of select="balance" /> <BR />Date: <xsl:value-of select="date" /> <BR /><BR /> </xsl:for-each> </xsl:for-each> </BODY> </HTML> </xsl:template> </xsl:stylesheet>

XSL Source: xslcustomers.xsl 

For the final parts of the question we do the following:

  • Client-Side Transformation - we need to add in one extra line into our XML document, which references the stylesheet and then simply open the XML document in our IE browser. Therefore we add the line:

           <?xml-stylesheet type='text/xsl' href='xslcustomers.xsl'?>
  • Manual Transformation - we perform this using Xalan at the command line:

         java -classpath .;xalan.jar org.apache.xalan.xslt.Process -IN 
        xslcustomers.xml -XSL xslcustomers.xsl -OUT xslcustomers.html

If you have created your stylesheet correctly, the output of either should be identical (or very close) to the original question requirement. One 'trick' which can be used for creating your stylesheet, so that your HTML is identical, is to view the source (right click on the page in IE) of the HTML document your wish to recreate. You can then see the HTML code necessary for displaying the page, which you can then utilize in your stylesheet.

XSLT and JAXP (Java API for XML Processing)

While server-side transformations may be performed using Xalan at command line, these are not real-time. Often it is necessary to perform transformations 'on-the-fly', creating customized HTML/XHTML/etc. views of your XML data. A simple example of this, is that you may wish to present your data in different ways depending on whether the client user is accessing your site using IE or Firefox or Chrome. The browser information is sent with the clients request and the server could then decide to render the HTML document in different ways. 

For this and many other reasons, we frequently need to be able to perform transformations from within our Java Applications. JAXP allows us to do this! There are four packages within JAXP, which we use for XSLT transformations:

  • javax.xml.transform - Defines the TransformerFactory and Transformer classes, which you use to get an object capable of doing transformations. After creating a transformer object, you invoke its transform() method, providing it with an input(source) and output(result).

  • javax.xml.transform.dom - Classes to create input(source) and output(result) from a DOM

  • javax.xml.transform.sax - Classes to create input(source) from a SAX parser and output(result) objects from a SAX event handler.

  • - Classes to create input(source) and output(result) objects from an I/O stream.

A TransformerFactory object is instantiated, and used to create a Transformer. The source object is the input to the transformation process. A source object can be created from SAX reader, from a DOM, or from an input stream. Similarly, the result object is the result of the transformation process. That object can be a SAX event handler, a DOM, or an output stream. When the transformer is created, it may be created from a set of transformation instructions, in which case the specified transformations are carried out. If it is created without any specific instructions, then the transformer object simply copies the source to the result.

Figure 3.7. JAXP XSLT API in Action

The following example shows the JAXP XSLT transformation API in action.

import javax.xml.transform.dom.DOMSource; import; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerConfigurationException; import; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.w3c.dom.Document; import org.w3c.dom.DOMException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import*; public class XMLtoHTML { public static void main (String argv[]) { try { if (argv.length < 3) { System.out.print("Usage: java XMLtoHTML <doc.xsl> <doc.xml>" + "<output.html>"); System.exit(1); } File stylesheet = new File(argv[0]); File xmlfile = new File(argv[1]); File output = new File(argv[2]); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(xmlfile); StreamSource xslsource = new StreamSource(stylesheet); TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer transformer = tFactory.newTransformer(xslsource); DOMSource source = new DOMSource(document); FileWriter writer = new FileWriter(output); StreamResult result = new StreamResult(writer); transformer.transform(source, result); } catch (SAXParseException spe) { System.out.println("\nParsing Error\n"); } catch (ParserConfigurationException pce) { System.out.println("\nParserConfigurationException!\n"); } catch (TransformerConfigurationException tce) { System.out.println("\nTransformerConfigurationException!\n"); } catch (TransformerException te) { System.out.println("\nTransformer Exception!"); } catch (SAXException se) { System.out.println("\nSAXException!"); } catch (IOException ioe) { System.out.println("\nIOException!"); } } }


Usage Example: java XMLtoHTML xslcustomers.xsl xslcustomers.xml customeroutput.html