Archive

Archive for the ‘XML + XSL + Java’ Category

Use Java to convert XML and XSL to HTML Web Page

October 27, 2011 Leave a comment

This example creates an HTML document from an xml file and xsl stylesheet. The HTML page is generated using a simple java application.

This example is based off a homework assignment I had in my advanced Java class. Specifically, i find the Driver class that creates an html file useful.

First create a valid xml document.

catalog.xml

<?xml version="1.0"?>
<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia Records</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>

    <cd>
        <title>Hide Your Heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>

    <cd>
        <title>Best of Enya</title>
        <artist>Enya</artist>
        <country>UK</country>
        <company>ABC Records</company>
        <price>9.90</price>
        <year>1995</year>
    </cd>
</catalog>

In the example xml file above we’ve created 3 music cd’s for our catalog. These will be rendered into a table in our HTML page. Each CD contains information including title, artist, etc. Notice the price field doesn’t contain a dollar sign ($). We will perform a test on the price field. If the price is greater than $10.00, the font is red. Otherwise, the price is green. Its not pretty but its practical.

catalog.xsl

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="/">
<html>

   <head>
      <title>CD Catalog</title>
      <style type="text/css">
        table {
            font-family: verdana;
        }

          tr {
              height: 30px;
          }

          td.col1 {
              width: 100px;
          }

          td.col2 {
              width: 400px;
          }

          td.title {
              background: #efe7d9 ;
              border-bottom: 1px solid #336699;
              font: 16 verdana;
              padding: 0 0 0 15px;
          }

          .red {
              color: #ff0000;
          }

          .green {
              color: #249821;
          }

          td.greenRow
          {
              background: #d6efd6;
              border-bottom: 1px solid #437841;

          }
      </style>
   </head>

   <body>
      <table>
         <xsl:for-each select="catalog/cd">
             <!-- if artist is assigned enya, set bg to green. -->
            <tr>
            <xsl:choose>
                   <xsl:when test="artist = 'Enya'">
                       <td colspan="2" class="greenRow">
                          <xsl:value-of select="title" />
                       </td>
                   </xsl:when>
                   <xsl:otherwise>
                       <td colspan="2"><xsl:value-of select="title" /></td>
                   </xsl:otherwise>
            </xsl:choose>
            </tr>
            <tr>
               <td>Artist:</td>
               <td><xsl:value-of select="artist" /></td>
            </tr>
            <tr>
               <td>Company:</td>
               <td><xsl:value-of select="company" /></td>
            </tr>
            <tr>
               <td>Country:</td>
               <td><xsl:value-of select="country" /></td>
            </tr>
            <tr>
               <td>Year:</td>
               <td><xsl:value-of select="year" /></td>
            </tr>
            <tr>
               <td>Price:</td>

               <!-- if price greater than $10, show in red.
                    Otherwise, show green -->
               <xsl:choose>
                       <xsl:when test="price &gt; 10">
                           <td class="green">
                              $<xsl:value-of select="price" />
                           </td>
                       </xsl:when>
                       <xsl:otherwise>
                           <td class="red">
                              $<xsl:value-of select="price" />
                           </td>
                       </xsl:otherwise>
               </xsl:choose>
            </tr>
         </xsl:for-each>
      </table>
    </body>
</html>
</xsl:template>
</xsl:stylesheet>

This is the xsl style sheet. This is the template for the HTML output. Its combined with several xsl conditional statements, specifically the for each loop and the “choose, when, otherwise” statement.

<?xml version=”1.0″?>
<xsl:stylesheet xmlns:xsl=”http://www.w3.org/1999/XSL/Transform&#8221; version=”1.0″>

In line 1, notice this is an xml document. Be sure to add this line.
<?xml version=”1.0″?>

The second line is the namespace. Add this line as well.
<xsl:stylesheet xmlns:xsl=”http://www.w3.org/1999/XSL/Transform&#8221; version=”1.0″>

In my opinion, the two lines above should be accepted for what they are and move on. For more information please reference the vast articles available.

<xsl:template match=”/”>
On the next line, you will notice the <xsl:template match=”/”></xsl:template>. The code embedded in the xsl:template nodes is your html + xsl commands. The attribute match=”/” references back to the root element of catalog.xml.

The root element in our example above is <catalog></catalog>. This style sheet will begin looking within the root element allowing us access to <cd></cd> node.

Building the table output
Naturally a table is data rendered in an easy to read format. In our example we create a table that looks like this:

HTML output using java program using XML and XSL document.

HTML output using java program using XML and XSL document.

We begin by creating a basic html table with no rows or columns.
<table></table>

Inside this table is where we loop through each node in the xml file. Each CD will have its own layout with title and other basic information. This loop creates each row appending the node information.

<xsl:for-each select=”catalog/cd”>

To accomplish this we use the for-each loop construct. A for each loop will loop through all nodes that we selected. As shown in the example below, the for each loop construct begins with the xsl tag prefix and select attribute.

The select attribute tells the for-each loop what you are looping through. We are interested in all CDs so we filter down to the cd. Separate each node with a slash. Looking back at our example, notice that catalog is the root xml element. The next node is cd. Hence catalog/cd will loop us through each CD where we can obtain all nodes within the cd. This includes artist, company, etc.

<xsl:choose>
<xsl:when test=”artist = ‘Enya'”>
<td colspan=”2″><xsl:value-of select=”title” /></td>
</xsl:when>
<xsl:otherwise>
<td colspan=”2″><xsl:value-of select=”title” /></td>
</xsl:otherwise>
</xsl:choose>

In the photo if you will notice that Enya is green. This is accomplished by the choose, when, otherwise construct. This is similar to a switch statement in java or select case in visual basic. This allows you to test for several situations and respond accordingly.

In my example, I am setting the background of the table row to green if the artist is Enya. A practical application might be to highlight a product that is on sale. In the example above, i test if the value of our node (<artist></artist>) equals “Enya”. If so, we display green background, otherwise we display default background color.

Notice I have done the same for the price. if the price is greater than $10.00 we display the output in red. If the price is less than $10.00, green font is used.

<xsl:value-of select=”title” />
To retrieve the content between the xml tags <artist>Enya</artist>, use xsl:value-of. For example, to retrieve the title of a CD, we use the <xsl:value-of tag and set the select attribute to title. This is the name of the node we are interested in (<title></title>).

Convert XML and XSL to HTML using Java

package xmlToHtml;

import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;

public class Driver {

    public static void main(String[] args)
    {
        try
        {
            TransformerFactory tFactory = TransformerFactory.newInstance();

            Source xslDoc = new StreamSource("src/xmlToHtml/catalog.xsl");
            Source xmlDoc = new StreamSource("src/xmlToHtml/catalog.xml");

            String outputFileName = "src/xmlToHtml/catalog.html";
            OutputStream htmlFile = new FileOutputStream(outputFileName);

            Transformer transformer = tFactory.newTransformer(xslDoc);
            transformer.transform(xmlDoc, new StreamResult(htmlFile));
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

And here is the code used to create an html file from the catalog.xml and catalog.xsl documents. In the code above, note that I create a stream source for both the xml and xsl files. Next an output stream is created which renders the proper html.

As you can see by my package name “xmlToHtml” and the relative paths to my xml and xsl files, I have my project files located in /src/xmlToHtml/ folder. Adjust this accordingly to suit your needs.

And the output generated from the java file:

catalog.html

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>CD Catalog</title>
<style type="text/css">
	table {
		font-family: verdana;
	}

	tr {
		height: 30px;
	}

	td.col1 {
		width: 100px;
	}

	td.col2 {
		width: 400px;
	}

	td.title {
		background: #efe7d9 ;
		border-bottom: 1px solid #336699;
		font: 16 verdana;
		padding: 0 0 0 15px;
	}

	.red {
		color: #ff0000;
	}

	.green {
		color: #249821;
	}

	td.greenRow
	{
		background: #d6efd6;
		border-bottom: 1px solid #437841;

	}
</style>
</head>
<body>
  <table>
    <tr>
        <td class="title" colspan="2">Empire Burlesque</td>
    </tr>
    <tr>
        <td class="col1">Artist:</td><td class="col2">Bob Dylan</td>
    </tr>
    <tr>
        <td class="col1">Company:</td><td class="col2">Columbia Records</td>
    </tr>
    <tr>
        <td class="col1">Country:</td><td class="col2">USA</td>
    </tr>
    <tr>
        <td class="col1">Year:</td><td class="col2">1985</td>
    </tr>
    <tr>
        <td class="col1">Price:</td><td class="col2 red">$10.90</td>
    </tr>
    <tr>
        <td class="title" colspan="2">Hide Your Heart</td>
    </tr>
    <tr>
        <td class="col1">Artist:</td><td class="col2">Bonnie Tyler</td>
     </tr>
     <tr>
        <td class="col1">Company:</td><td class="col2">CBS Records</td>
    </tr>
    <tr>
        <td class="col1">Country:</td><td class="col2">UK</td>
    </tr>
    <tr>
        <td class="col1">Year:</td><td class="col2">1988</td>
    </tr>
    <tr>
        <td class="col1">Price:</td><td class="col2 green">$9.90</td>
    </tr>
    <tr>
        <td class="title greenRow" colspan="2">Best of Enya</td>
    </tr>
    <tr>
        <td class="col1">Artist:</td><td class="col2">Enya</td>
    </tr>
    <tr>
        <td class="col1">Company:</td><td class="col2">ABC Records</td>
    </tr>
    <tr>
        <td class="col1">Country:</td><td class="col2">UK</td>
    </tr>
    <tr>
       <td class="col1">Year:</td><td class="col2">1995</td>
    </tr>
   <tr>
       <td class="col1">Price:</td><td class="col2 green">$9.90</td>
    </tr>
</table>
</body>
</html>
Categories: XML + XSL + Java