PART-3

       

          XSLT PROCESSING USING XALAN IN JAVA

 

R.S.RAMASWAMY

    rs.ramaswamy.gmail.com

 

 

            In this third part of the tutorial on XSLT IN ASP.Net & J2EE, we  the favourite XSLT processor of the Java World, namely Apache-Xalan. We will illustrate the various methods using xalan-1 & xalan-2 and also explains the TrAX API in jaxp1.1 in jdk1.4 as applied in console programs, servlet and also JSP.

 

    The following table shows the various xslt processors.

 

Processor

Language

From

XT

Java

James Clark

Xalan

C++ and Java

IBM/Apache

Oracle XSLT

C++ and Java

Oracle

Saxon

Java

Michael Kay

MSXML

C++

Microsoft

XML::XSLT

Perl

SourceForge

 

 

    XALAN , was previously known as LotusXSL  and  was originally developed in IBM labs under the leadership of Scott Boag. Later, it was handed over to Apache Foundation for further development as an open source project. At that time , it was known as

 xalan-1. Subsequently, there have been a number of changes and the current version is  xalan-2.

    Many books, published about 5 years back, (around  1999),refer to xalan and xerces and give code examples. Unfortunately, much of the code examples , will neither compile nor run, unless the  xalan version-1 is used along with the corresponding xerces processor. Therefore, we will see a simple example using xalan-1 first and then changeover to xalan-2 given  in jdk1.4.    We are using xalan1.0 and corresponding xerces. As we do not want to use the latest xalan (ie) version2, available in jaxp1.1 of jdk1.4, we will give path to

   d:\jdk1.3\bin only. We may be unable to get xalan1.0 , from the web now! We can get it from the CD associated with 'Applied XML Solutions ' by a famous & brilliant author 'Benoit Marchal'( Techmedia pub).The same version is referred to by another famous book 'XML Development with Java2' by Michael Daconta(Techmedia).

 

   First and foremost , install xalanj as xalan1 in

C:\ drive .We can find a number of very valuable jar files in this folder.

     a)  xalan.jar

     b)  xerces.jar

     c)  bsf.jar   ( bean scripting framework)

     d)  bsfengines.jar

 

And also a lot of useful documents and references.

 

---------------------------------------

    We begin by editing

         ' g:\xslt\xsltester.java'

 

 

//  g:\xslt\xsltester.java

 

import org.apache.xalan.xslt.*;

 

 

class xsltester

{

   public static void main(String args[])

   {

      try

      {

         XSLTProcessor         processor=

                      XSLTProcessorFactory.getProcessor();

 

         XSLTInputSource      a=

                     new XSLTInputSource("students.xml");

 

         XSLTInputSource      b=

                          new XSLTInputSource("xsl1.xsl"); 

 

         XSLTResultTarget    c=

                      new XSLTResultTarget("result.htm");

 

         processor.process(a,b,c);

 

         System.out.println(“Output ready!see result.htm");

 

      }   catch(Exception e1)

       {  System.out.println(""+e1);  }

   }

}

----------------------------------------------------------

The class-nomenclature  is absolutely streamlined and intuitive.

 

    g:\xslt>set path=

         c:\windows\command;d:\jdk1.3\bin

 

     g:\xslt>set classpath=

         g:\xslt;c:\xalan1\xalan.jar;

                 c:\xalan1\xerces.jar

 

Now we are ready to compile .

 

   >javac xsltester.java     //  compile

  It will compile without hitch.

 

Now place students.xml & xsl1.xsl in

   g:\xslt   folder and execute the program.

  

   >java xsltester           //  execute

 

   We will get the message:

    'output ready!..see result.htm'

we can check up by seeing result.htm!

**********************************************************

 

That was about getting the transformation done by a Java program. But,   We can also get the same result without writing    any java code, from command line.

 

  >java  org.apache.xalan.xslt.Process

                     -in students.xml

                      -xsl  xsl1.xsl > result.htm

( to be typed continuously)

 

     we get the following messages:

 

  parsing  xsl1.xsl     .....219  milli-seconds

  parsing  students.xml   ....31       ,,

  transforming ...............16       ,,

  Is it not super-fast?

   We can now see result.htm in console or in browser.KINDLY NOTE THAT  THE ABOVE CODE WILL NOT WORK WITH XALAN2 IN JAXP1.1 OF JDK1.4

 

 

   We now see how we can use jdk1.4 for transformations.

we  begin by using xalan2  in jdk1.4

   All that we have to do is to type the following command

   ( assuming that we have already done the following:

      set path=c:\windows\command;d:\jdk1.4\bin

    Remember to place  students.xml &  xsl1.xsl in     the current folder).

 

   >java  org.apache.xalan.xslt.Process  

                       -in  students.xml

                       -xsl  xsl1.xsl

                       -out   traxout.htm

   ( the command should be typed in a single line)

  

    After this we can verify traxout.htm

 

-----------------------------------------------

    xalan2 xslt processor is built into jaxp1.1 and jdk1.4  incorporates jaxp1.1.  We can see traxout.htm in browser .( Towards the end of this tutorial, we will be referring to the super-fast and easy method of testing the transformation., So kindly make a special note.)

 

 When we want programmatic execution, we can use a program as follows:

 

 

// console mode java

//   g:/trax/traxbeanconsole.java

import java.io.*;

import javax.xml.transform.*;

import javax.xml.transform.stream.*;

  // set path=c:\windows\command;d:\jdk1.4\bin

  // set classpath=<current folder>( g:\trax)

 

class traxbeanconsole

{

   public static void main(String args[])

   {

 

      traxbean    bean1 = new traxbean();

 

      String   a = args[0];   //  xsl file

      String   b = args[1];   //  xml file

      String   c = args[2];   // output file

 

       bean1.doTrax(a,b,c);

   

    }

 }

 //-------------------------------------------------

 

  class  traxbean   // user -defined class

    {

 

         traxbean()

           {  }

 

  public  void  doTrax

              (String  a, String b, String c)

      {

       try

         {

 

        TransformerFactory    factory=      

                      TransformerFactory.newInstance();

 

        StreamSource  xsl=   new StreamSource(a);   

              

        Transformer   transformer=

                          factory.newTransformer(xsl);

 

        StreamSource    xml= new StreamSource(b);

 

        StreamResult    result= new StreamResult(c);

 

        transformer.transform(xml,result);

 

        System.out.println("result sent to traxdemo.htm");

        System.out.println("try 'type traxdemo.htm' ");

 

      }catch(Exception e1)  { System.out.println(""+e1); }

 }// function

}// inner class

 

 

 

 

===============================================

     The console mode example given above will work only in jdk1.4, which incorporates JAXP1.1 , with built in support for TrAX API and Namespaces. Unlike xalan-1 , we don't have to give classpath.

 

  Let us create this file in

 g:\trax\traxbeandemo.java

 

  >set path=c:\windows\command;d:\jdk1.4\bin

  We will be able to compile.

  Run the program as,

 > java traxbeanconsole  

      xsl1.xsl students.xml  result.htm

 

we get message as :

  >result sent to result.htm

        try 'type result.htm'

-------------------------------------------

 

   Explanation for the code follows.

 

   The main program simply creates an instance of the traxbean class and invokes the bean's method 'doTrax' with three parameters , namely, xslfile,xmlfile and outputfile.

 

    The bean's code begins with the creation of TransformerFactory instance.   This is the common pattern in all the JAXP programs. The Transformer instance is to be created next but it takes the xsl file as a parameter.

So, we have to define it first. The xsl may come from a StreamSource or DomSource or SaxSource.For simplicity, we assume a StreamSource. Now, we create the instance of Transformer.

 

     After this, we can ask the transformer  to transform, but we have to give two parameters when invoking this command. First parameter is the StreamSource of the XML file to be transformed and the second parameter is the  StreamResult specifying the name of the output file. Finally, we invoke the transform command on the transform object.  It 'cannot get any simpler'.

-----------------------------------------------    

   If you get the message that there is no class 'traxbeandemo', set classpath=g:\trax  and try again.   Let us now see how we can modify the program to be used as a servlet.

 

------------------------------------------------

Create the file as

   g:\xslt\traxdemoservlet.java  

 

import java.io.*;

import java.net.*;

import javax.xml.transform.*;

import javax.xml.transform.stream.*;

 

import javax.servlet.*;

import javax.servlet.http.*;

 

 

public class traxdemoservlet

                       extends HttpServlet

{

 

    public void doPost

          (HttpServletRequest request,

                 HttpServletResponse response)                                     

                    throws

                  IOException,ServletException

     {

    response.setContentType("text/html");

    PrintWriter   out = response.getWriter();

 

  String  a = request.getParameter("text1");

  String  b = request.getParameter("text2");

 

        a="http://localhost:8080/"+a;

        b="http://localhost:8080/"+b;

 

            traxbean   bean1 = new traxbean();

             String   v= bean1.doTrax(a,b);

        out.println(v);  // send it to browser

          }

         

 

     //-------inner class follows----------

 

    class traxbean

    {

 

       traxbean()   {   }  // constructor

 

  public String     doTrax(String a, String b)

        {

            String   r = "";

 

       try

       {

 

        TransformerFactory factory=

                   TransformerFactory.newInstance();

 

        StreamSource     xsl=new StreamSource(a);

                //  'http://localhost:8080/xsl1.xsl'

                  

        Transformer   transformer=

                        factory.newTransformer(xsl);

 

        StreamSource    xml= new StreamSource( b);                      

               //("http://localhost:8080/students.xml");

 

        StreamResult result=

               new StreamResult     ("g://traxdemo.htm");

 

         transformer.transform(xml,result);

 

      FileInputStream       fis=

                new FileInputStream("g://traxdemo.htm");

 

      DataInputStream  ins=new DataInputStream(fis);

        

        String s=ins.readLine();

           while(s   !=   null )

           {

            r = r+s+"<br>";

           s=ins.readLine();

           }

     }catch(Exception e1)    { System.out.println(""+e1);}

 

      return   r;

 

 

    }

   // ================  inner class over =========

 

}

===============================================

  To compile the above servlet file, we have to set  correct  path  & classpath:

  g:\xslt>

set path=c:\windows\command;d:\jdk1.4\bin 

set classpath=e:\tomcat32\lib\servlet.jar

   Now, we will be able to compile.

 After compiling, we copy the servlet's classfile to:

  'e:\tomcat32\webapps\root\web-inf\classes'  

  Remember to copy the classfile of the servlet's inner-class also.

 'traxdemoservlet$traxbean.class'

This is very important.

 ( Also, remember that tomcat should be restarted, if any new servlet class is placed or modified).   

  

 Place 'students.xml'  and 'xsl1.xsl' in :

    'e:\tomcat32\webapps\root'   folder.

   

It will be noticed that the location of xml file and xsl file is given  as:

 "http://localhost:8080/students.xml" and

"http://localhost:8080/xsl1.xsl" in the servlet.

 

 But the output file is hard-coded in simple windows style.   The output file is read by FileInputStream and each line is sent to the browser.

 

  We place the calling html file in root folder oftomcat.

Type data as 'xsl1.xsl' in text1 &  'students.xml' in text2  and submit.

 

In    PART4    we will see   XSLT  in JSP.