Transforming XML to HTML

Until all browsers support processing XML and XSL in a standard and efficient manner, it is better to transform XML into HTML for presentation on the browser. Servlets, as Java programs, can use a range of XML parsers and XSL engines to transform XML to HTML. I chose to use James Clark's XSL Transformation engine, XT. You can download XT from http://www.jclark.com/xml.

James Clark's XT Program

XT is an open source Java implementation of the XSL Transformation specification. James Clark is the author of both XT and the XSL Transformation specification for the W3C. XT can be used as a standalone application to generate a result document given the names of an XML document and stylesheet on the command line. The command-line arguments for XT are as follows:

java -Dcom.jclark.xsl.sax.parser=your-sax-driver com.jclark.xsl.sax.Driver source
 stylesheet_file result_file name=value...

To use XT on the command line, you run the class com.jclark.xsl.sax.Driver. XT requires a SAX parser that you specify using the com.jclark.xsl.sax.parser System property using the -D argument to the JVM. After specifying the stylesheet file and the result file, you can optionally specify any number of name=value pairs to be used as parameters in the stylesheet. However, the parameters will only be used if the stylesheet has corresponding xsl:param elements.

XT can also be used programmatically and exposes two types of programming interfaces—one based on SAX and the other based on DOM. It is also possible to mix both interfaces using a DOM for input and generating the result document via a SAX interface. This is the strategy demonstrated in the AphorismsToHtmlTbl servlet.

The previous section discussed the generation of the XML document via the ProcessAphorismForm servlet. To transform that XML document into HTML, we need a stylesheet with the appropriate template. Listing 9.5 presents a simple stylesheet to convert an Aphorisms Markup Language document into an HTML document with a table where each row is selected fields of the aphorism record.

Code Listing 9.5. An XSL Stylesheet to Convert XML to HTML
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match = "/">
    <html>
    <head>
        <title> Aphorisms Table </title>
    </head>

    <body>
    <CENTER> <H1> The Aphorisms List </H1> </CENTER>
    <CENTER>
    <table width="100%" border="2">
    <tr>
        <th> Title </th>
        <th> Source </th>
        <th> Aphorism </th>
    </tr>
    <xsl:for-each select="APHORISMS/APHORISM_RECORD">
    <tr>
    <td> <xsl:value-of select = "TITLE" /> </td>
    <td> <xsl:value-of select = "SOURCE" /> </td>
    <td> <xsl:value-of select = "APHORISM" /> </td>
    </tr>
    </xsl:for-each>
    </table>
    </CENTER>
    </body>
    </html>
</xsl:template>
</xsl:stylesheet>

The stylesheet consists of a single template that matches the root of the document. Because the Aphorisms Markup Language is uniform with only a single set of children, I can process the document using an xsl:for-each element. After matching each APHORISM_RECORD, I use xsl:value-of to extract the XML subelements TITLE, SOURCE, and APHORISM as table date items in the table row. This stylesheet will be used by the XSLProcessorImpl class of the XT distribution in the AphorismsToHtmlTbl servlet.

The AphorismsToHtmlTbl Servlet

The AphorismsToHtmlTbl servlet generates the HTML table displayed in Figure 9.4. The HTML table will contain one row for each APHORISM_RECORD in the APHORISMS XML document.

Figure 9.4. The Aphorisms XSL-generated HTML table.


Listing 9.6 is the source code for the AphorismsToHtmlTbl servlet. The servlet extends HttpServlet and implements two SAX interfaces—DocumentHandler and ErrorHandler. The servlet assumes that the XML input file and the XSL stylesheet are in the same directory as the servlet. The servlet will fail if that is not the case. The servlet uses the XslProcessImpl class from the XT distribution to programmatically generate a result document from the input document and the stylesheet.

Code Listing 9.6. AphorismsToHtmlTbl.java
/* AphorismsToHtmlTbl.java */
package sams.chp9;

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;

import com.sun.xml.tree.XmlDocument;
import org.xml.sax.*;
import org.w3c.dom.*;

import com.jclark.xsl.sax.*;
import com.jclark.xsl.dom.*;

public class AphorismsToHtmlTbl extends HttpServlet
                                implements DocumentHandler, ErrorHandler
{
    static final String inputfile = "Aphorisms.xml";
    static final String sheetfile = "aphorismtbl.xsl";

    PrintWriter pw;

    /** Locator reference. */
    Locator loc;

    public void service(HttpServletRequest req, HttpServletResponse res)
    {
        try
        {
            res.setContentType("text/html");
            pw = res.getWriter();

            File in = new File(inputfile);
            if (!in.exists())
            {
                pw.println("<HTML> <HEAD> <TITLE> Aphorisms TABLE </TITLE>" +
                   "</HEAD> <BODY> <H1> No Aphorisms entered. </H1> " +
"</BODY> </HTML>");
                return;
            }

            File sheet = new File(sheetfile);
            if (!sheet.exists())
            {
                pw.println("<HTML> <HEAD> <TITLE> Aphorisms TABLE </TITLE>" +
                  "</HEAD> <BODY> <H1> Error: No XSL Stylesheet. </H1> " +
                            "</BODY> </HTML>");
                return;
            }
            // create a SAX InputSources
            InputSource is = new InputSource(in.toURL().toString());
            InputSource sis = new InputSource(sheet.toURL().toString());

            // create a Sun DOM Xml Processor impl
            SunXMLProcessorImpl sunImpl = new SunXMLProcessorImpl();

            // create an XT XSL processor
            XSLProcessorImpl xslProcessor = new XSLProcessorImpl();

            // set the Sun impl to use a DOM as input
            xslProcessor.setParser(sunImpl);

            // load the stylesheet
            xslProcessor.loadStylesheet(sis);

            // set Document Handler
            xslProcessor.setDocumentHandler(this);

            // set Error Handler
            xslProcessor.setErrorHandler(this);

            // parse input
            xslProcessor.parse(is);
       }  catch (Exception e)
          {
            e.printStackTrace();
            try
            {
                res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }  catch (IOException ioe) {  }
          }
    }

    /** method of the DocumentHandler Interface. */
    public void characters(char[] ch, int start, int length)
    {
        // Receive notification of character data inside an element.
        pw.print(new String(ch,start,length));
    }

    /** method of the DocumentHandler Interface. */
    public void endDocument()
    {
        // Receive notification of the end of the document.
        pw.println("</BODY> </HTML>");
    }

    /** method of the DocumentHandler Interface. */
    public void endElement(java.lang.String name)
    {
        // Receive notification of the end of an element.
        pw.println("</" + name +">");
    }

    /** method of the DocumentHandler Interface. */
    public void ignorableWhitespace(char[] ch, int start, int length)
    {
        // Receive notification of ignorable whitespace in element content.
    }

    /** method of the DocumentHandler Interface. */
    public void processingInstruction(java.lang.String target,
                               java.lang.String data)
    {
        // Receive notification of a processing instruction.
    }

    /** method of the DocumentHandler Interface. */
    public void setDocumentLocator(Locator locator)
    {
        // Receive a Locator object for document events.
        loc = locator;
    }

    /** method of the DocumentHandler Interface. */
    public void startDocument()
    {
        // Receive notification of the beginning of the document.
        pw.println(
           "<HTML> <HEAD> <TITLE> Aphorisms TABLE </TITLE> </HEAD> <BODY>");
    }

    /** method of the DocumentHandler Interface. */
    public void startElement(java.lang.String name, AttributeList attributes)
    {
        // Receive notification of the start of an element.
        pw.print("<" + name + " ");
        for (int i = 0; i < attributes.getLength(); i++)
        {
            String attName = attributes.getName(i);
            String type = attributes.getType(i);
            String value = attributes.getValue(i);
            pw.print(attName + "=" + value + " ");
        }
        pw.println(">");
    }

    /** method of the ErrorHandler Interface. */
    public void error(SAXParseException e)
    {
        // Receive notification of a recoverable parser error.
        pw.println("Error Parsing XML! Reason:" + e + "<BR>");
        pw.println("In " + loc.getSystemId() + ",at line " +
                    loc.getLineNumber() + " and col " +
                    loc.getColumnNumber() + "<BR>");
    }

    /** method of the ErrorHandler Interface. */
    public void fatalError(SAXParseException e)
    {
        // Report a fatal XML parsing error.
        pw.println("FATAL Error Parsing XML! Reason:" + e + "<BR>");
        pw.println("In " + loc.getSystemId() + ",at line " +
                    loc.getLineNumber() + " and col " +
                    loc.getColumnNumber() + "<BR>");
    }

    /** method of the ErrorHandler Interface. */
    public void warning(SAXParseException e)
    {
        // Receive notification of a parser warning.
        pw.println("Warning Parsing XML! Reason:" + e + "<BR>");
        pw.println("In " + loc.getSystemId() + ",at line " +
                    loc.getLineNumber() + " and col " +
                    loc.getColumnNumber() + "<BR>");
    }
}

Note the following points about Listing 9.6:

  • The service() method is invoked when the client clicks the link from Aphorisms.html (displayed in Figure 9.1) to display the current list of aphorisms. The method first checks to see if the XML input file (aphorisms.xml) and the XSL stylesheet (aphorismtbl.xsl) exist in the current directory. If not, a simple HTML page is sent to the browser with an appropriate error message. If the files exist, SAX InputSource objects are created from the File objects. A SunXMLProcessorImpl object is instantiated as the parser implementation for the XSL processor. After creating an XSLProcessorImpl object, I set the SunXMLProcessorImpl as the parser using the setParser() method. the SunXMLProcessorImpl will parse an XML document and generate a DOM object from it. After the parser has been set, I load the stylesheet, set the SAX Document handler, set the SAX error handler, and parse the input. Parsing the input using the XSLProcessorImpl object generates a result document by firing SAX events. The object (which is set to "this") set as the DocumentHandler will receive those SAX events.

  • The SAX handler methods simply translate the parameters passed into them into an HTML stream that is sent to the client browser. There is hardly any translation needed because the SAX Document handler methods are designed for XML documents. Also, there is no need to worry about the proper ordering of output to the browser because SAX events will be fired in the proper order.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.160.156