Tuesday, July 26, 2011

How to use XML and XSL in Java?

Almost everyday, somewhere we come across XML and we know that many systems use XML as their data store; more precisely, they talk in XML language.

Now, how do I write an application where I need to present the data, which is in XML format, to users? Is it possible to write XML processing application in Java?

Yes, Java SE provides extensive support for XML parsing and processing. Java supports two types of XML parsers, viz, SAX and DOM. These parsers and their supporting classes are collectively called JAXP, Java API for XML Processing.

Now given a XML document, how do I transform it in a user presentable format rather than parsing the XML document? Or do I need to parse the XML to transform it?

No and may be. No - you don't have to parse it to transform it; java will do it for you with the help of XSL. May be - if you want to.

Enough of theory. Let's program. Here is the sample XML file.
<?xml version="1.0" encoding="UTF-8"?>
<report
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:w ='http://xml.netbeans.org/schema/newXmlSchema'>
<students>
<student>                      
  <name>Joanus</name>
  <marks>
      <maths>80</maths>
      <physics>75</physics>
      <chemistry>90</chemistry>
      <biology>96</biology>
  </marks>
</student>              
<student>                      
  <name>Shawn</name>
  <marks>
      <maths>90</maths>
      <physics>73</physics>
      <chemistry>79</chemistry>
      <biology>98</biology>
  </marks>
</student>
<student>                      
  <name>Jarius Asir</name>
  <marks>
      <maths>70</maths>
      <physics>74</physics>
      <chemistry>89</chemistry>
      <biology>68</biology>
  </marks>
</student>
<student>                      
  <name>Janola Violet</name>
  <marks>
      <maths>100</maths>
      <physics>65</physics>
      <chemistry>90</chemistry>
      <biology>88</biology>
  </marks>
</student>
</students>
</report>


I want to render this data in a tabular format to the user. Let's write the XSL as follows.


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

<xsl:template match="/">
<html>
  <head>
      <style type="text/css">
          #top-table
          {
              border-collapse:collapse;
          }
          #top-table td, #top-table th
          {
              font-size:1em;
              border:1px solid #98bf21;
              padding:3px 7px 2px 7px;
          }
          #top-table th
          {
              font-size:1.1em;
              text-align:left;
              padding-top:5px;
              padding-bottom:4px;
              background-color:#A7C942;
              color:#ffffff;
          }
          #top-table tr.alt td
          {
              color:#000000;
              background-color:#EAF2D3;
          }
      </style>
  </head>
  <body>
      <xsl:apply-templates select="/report/students"/>
  </body>
</html>
</xsl:template>

<xsl:template match="students">
<table id="top-table">
  <thead>
      <tr>
          <th>Student's Name</th>
          <th>Maths</th>
          <th>Physics</th>
          <th>Chemistry</th>
          <th>Biology</th>
      </tr>
  </thead>
  <tbody>
      <xsl:apply-templates select="student"/>
  </tbody>
</table>
</xsl:template>

<xsl:template match="student">
<xsl:choose>
  <xsl:when test="position() mod 2 > 0">
      <tr class="alt">
          <xsl:apply-templates select="name"/>
          <xsl:apply-templates select="marks"/>
      </tr>
  </xsl:when>
  <xsl:otherwise>
      <tr>
          <xsl:apply-templates select="name"/>
          <xsl:apply-templates select="marks"/>
      </tr>
  </xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template match="name">
  <td>
      <xsl:value-of select="."/>
  </td>
</xsl:template>
<xsl:template match="marks">
  <td><xsl:value-of select="maths"/></td>
  <td><xsl:value-of select="physics"/></td>
  <td><xsl:value-of select="chemistry"/></td>
  <td><xsl:value-of select="biology"/></td>
</xsl:template>
</xsl:stylesheet>

The Java code that transforms the above XML to HTML is as follows

import java.io.File;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

/**
* Translates XML into HTML using XSL
* @author Pragalathan M
*/
public class Main {

/**
* @param args the command line arguments
*/
public static void main(String[] args) throws TransformerException, Exception {
   File xmlFile = new File("xml/student-marks.xml");
   File xsltFile = new File("xml/student-marks.xsl");
   Source xmlSource = new StreamSource(xmlFile);
   Source xsltSource = new StreamSource(xsltFile);
   Result result = new StreamResult(System.out);

   TransformerFactory transFactory = TransformerFactory.newInstance();

   Transformer transformer = transFactory.newTransformer(xsltSource);
   transformer.transform(xmlSource, result);
}
}

Generated output looks like this.

Student's NameMathsPhysicsChemistryBiology
Joanus80759096
Shawn90737998
Jarius Asir70748968
Janola Violet100659088