Graphic JavaCreate XML files using JSP
- By David Geary
A FREQUENTLY ASKED question on the JSP mailing list is, "Can I create XML files using JSP?" This column answers that question and more, with a modest Web application that generates an XML file from the application's data. That XML file is subsequently processed with Extensible Stylesheet Language Transfomation (XSLT) to produce HTML.
Our example, shown in Figure 1, is an auction. All our auction can do is display its inventory—a list of items where each item has a name, description, and price. Listing 1 shows the code for the JSP page in Figure 1.
Figure 1. The auction.
This JSP page uses two tag libraries, each of which has exactly one tag. The tag libraries are defined by tag library descriptor (TLD) files, which are specified as the uri attribute for the taglib directive. Note: The TLDs are not listed here to save space. You can download the complete code for this article by clicking here.
The inventory:update tag produces an XML file, specified by the filename attribute, that represents the auction's inventory. That file looks like this:
from the early 1700's
... more items ...
tag applies XSLT to an XML file. Depending on the XSLT, XML can be translated to HTML, WML, another XML file, or any other desired format. In the case of the auction, the XML listed is translated into HTML, as shown in Figure 1.
Notice that the TLDs are in the application's WEB-INF/tlds directory. The reason for this is discussed in the next section, which provides a short overview of the application's files.
Application Directory Structure
The auction application consists of one JSP file, (see Listing 1), two custom tags, three beans, and an XSLT file. Those files are arranged in a directory hierarchy shown in Figure 2. The application's document root—xsl—contains only the JSP file and the WEB-INF directory.
Figure 2. The auction directory structure.
The WEB-INF directory is where applications store components such as servlets, Java beans, and JSP custom tags. The WEB-INF directory is special because none of its files can be served directly to a client; therefore, the auction application stores all files that should not be directly accessed, including TLDs, under the WEB-INF directory. Storing TLDs in a WEB-INF/tlds directory, as is the case for the auction application, is recommended but not required.
WEB-INF/classes is for servlets, utility classes, and Java beans. Typically, Web applications use a WEB-INF/classes/com/companyName directory structure for beans and custom tags. The auction application follows suit, with separate directories for different kinds of beans and tags. Sun's 2.2 Servlet specification provides a more complete discussion of Web applications and their directory structure.
The rest of this article is concerned with the two tasks implemented by the auction's JSP file: generating XML for the auction's inventory and transforming the XML with XSLT to produce HTML.
For the auction, generating XML is the responsibility of the application's model beans: Inventory and Item, from the com.companyName.beans.model package. Both beans implement printXml methods that print the bean, as XML, to a print stream.
The auction's XML generation begins with the inventory:update tag. The tag's handler is the UpdateInventoryTag class, (see Listing 2). Even if you know nothing about implementing JSP custom tags, it's pretty evident what UpdateInventoryTag does: At the end of the tag, the auction's inventory is printed as XML to the file specified by the filename attribute.
The simplicity of the UpdateInventoryTag class stems from encapsulating as much functionality as possible in beans; in this case, the Inventory and Item beans. The Inventory class is straightforward, as can be seen from Listing 3. Inventory consists of a vector of items, and the Inventory class creates the items shown in Figure 1 in its constructor. Inventory.printXml prints its items, surrounded by an inventory tag, to a print stream.
The Item class is shown in Listing 4. In the interest of space, simple setter and getter methods for the name, description, and price properties are omitted from the listing. The printXml method called by Inventory.printXml prints an item as XML to a print stream.
Equipping beans to print themselves as XML is a common technique, but it is not the only option for generating XML. For example, Java reflection could be used to produce XML for any object based on the object's properties. Using reflection is more dynamic because XML generation can be modified at runtime, which is not the case for self-printing beans.
XML files are meant to be shared. For example, the XML file generated by our auction could be read by any application that understands the inventory definition. XML files are not meant to be viewed directly in a browser; instead, XSLT can be used to transform XML into some other format, such as HTML for browsers or WML for wireless devices.
Transforming XML with XSLT requires two things: an XSLT processor and an XSLT file that specifies the transformation. There are a number of freely available XSLT processors, the most popular of which is the XT processor. If you download the code for this article, you must also download XT and install it, which is a simple task.
The auction's XML is transformed into HTML by the xsl:apply tag (see Listing 5). The tag has two required attributes: the name of an XML file and the name of a URL that points to an XSLT file. Those attributes are used by an instance of XslServletBean based on a servlet example that comes with the XT processor, which performs the actual transformation. Listing 6 provides truncated code for the bean; enough of the class is listed to provide a high-level overview of using the XT processor.
The loadProcessor method (not listed) sets up the processor for the specified XSLT file. The setOutput-MethodHandler method sets the processor's output stream to the output stream of the servlet response. Therefore, when the XSLT is applied to the XML file, the result of the transformation is sent to the response associated with the JSP's generated servlet.
The final piece of the puzzle is the XSLT file itself (see Listing 7). XSLT files contain a set of template rules specified with an xsl:template tag. Template rules match nodes in the XML document tree, and the body of the xsl:template tag is inserted in place of the node. For example, the first template rule in Listing 7 matches the XML document's root node, which is replaced with the body of the tag. The xsl:apply-templates tag inserts the text of the node, if any, and processes the node's children, looking for matching template rules. In so doing, the XSLT file in Listing 7 builds an HTML table with an item in each row.
JSP, Java, and XML are a formidable threesome that enables Web applications to collaborate by sharing data. XSLT can be used to transform XML into any desired format, allowing Web applications to run on various devices, from browsers to PDAs. For example, it is a simple matter to provide an alternate XSLT file for the auction that generates WML.
I've illustrated one way to generate XML from Java beans and one way to transform that XML into HTML. However, there are many ways to use JSP, Java, XML, and XSLT together. For example, JSP scriptlets can be embedded in XML just as they are in HTML, which offers another method for generating XML files.
Download the complete code for this article.