XML
  Home arrow XML arrow Page 4 - XSL Transformation With Xalan
Dev Shed Forums  
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Smartphone Development  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Mobile Linux  
App Generation ROI  
IBM® developerWorks  
Forums Sitemap  
E-Commerce Hosting  
Linux Web Hosting  
Managed Hosting  
Small Business Hosting  
VPS Hosting  
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid  
Request Media Kit
Contact Us  
Site Map  
Privacy Policy  
Support  
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
Google.com  
XML

XSL Transformation With Xalan
By: icarus, (c) Melonfire
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: starstarstarstarstar / 7
    2002-03-20


    Table of Contents:
  • XSL Transformation With Xalan
  • The Introductions
  • Meeting The World's Greatest Detective
  • The Anatomy Of A Transformation
  • The Write Stuff
  • Still Hungry?

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      error-file:tidyout.log Del.ici.ous error-file:tidyout.log Digg
      error-file:tidyout.log Blink error-file:tidyout.log Simpy
      error-file:tidyout.log Google error-file:tidyout.log Spurl
      error-file:tidyout.log Y! MyWeb error-file:tidyout.log Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article

     
     
    ADVERTISEMENT


    XSL Transformation With Xalan - The Anatomy Of A Transformation
    ( Page 4 of 6 )

    As always with Java, the first step involves pulling all the required classes into the application.

    // import required classes import javax.xml.transform.*; import javax.xml.transform.stream.*; import java.io.*;
    In case you're wondering, first come the classes for JAXP, followed by the classes for exception handling and file I/O. Now, I bet you're wondering, what's JAXP? According to the Unofficial JAXP FAQ, available at http://xml.apache.org/~edwingo/jaxp-faq.html, the Java API for XML Processing (JAXP) "enables applications to parse and transform XML documents using an API that is independent of a particular XML processor implementation". Or, to put it very simply, JAXP provides an abstraction layer, or standard API, that allows for code reuse across different XSLT processors. You might be wondering how JAXP, as an abstraction layer, knows which class to use during the transformation process. This information is available via the javax.xml.transform.TransformerFactory property. In case this didn't make any sense to you, don't worry about it; if it did, and you want to know more, take a look at http://xml.apache.org/xalan-j/apidocs/javax/xml/transform/TransformerFactory.html Next, I've instantiated some variables to hold the names of the various files I'll be using in the application.

    // store the names of the files public static String xmlFile, xslFile, resultFile = "";
    And now for the constructor:

    // constructor public addressBookConverter(String xmlFile, String xslFile, String resultFile) { try { // create an instance of the TransformerFactory // this allows the developer to use an API that is independent of // a particular XML processor implementation. TransformerFactory tFactory = TransformerFactory.newInstance(); // create a transformer which takes the name of the stylesheet // as an input parameter Transformer transformer = tFactory.newTransformer(new StreamSource(xslFile)); // transform the given XML file transformer.transform(new StreamSource(xmlFile), new StreamResult(resultFile)); System.out.println("Done!"); } catch (TransformerException e) { System.err.println("The following error occured: " + e); } }
    The first step is to create an instance of the TransformerFactory class. This can be used to create a Transformer object, which reads the XSLT stylesheet and converts the templates within it into a Templates object. This Templates object is a dynamic representation of the instructions present in the XSLT file - you won't see any reference to it in the code above, because it all happens under the hood, but trust me, it exists.

    Once the stylesheet is processed, a new Transformer object is generated. This Transformer object does the hard work of applying the templates within the Templates object to the XML data to produce a new result tree, via its transform() method. The result tree is stored in the specified output file.

    Finally, the main() method sets the ball in motion:

    // everything starts here public static void main (String[] args) { if(args.length != 3) { System.err.println("Please specify three parameters:n1. The name and path to the XML file.n2. The name and path to the XSL file.n3. The name of the output file."); return; } // assign the parameters passed as input parameters to // the variables defined above xmlFile = args[0]; xslFile = args[1]; resultFile = args[2]; addressBookConverter myFirstExample = new addressBookConverter (xmlFile, xslFile, resultFile); }
    This method first checks to see if the correct number of arguments was passed. If so, it invokes the constructor to create an instance of the addressBookConverter class; if not, it displays an appropriate error message.{mospagebreak title=Six Degrees Of Separation} Let's move on to something a little more complicated. Let's suppose that I wanted to convert my address book from XML into a delimiter-separated ASCII file format, for easy import into another application. With XSLT and Xalan, the process is a snap.

    Here's the XML data:

    <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="/home/me/xsl/xml2csv.xsl"?> <addressbook> <item> <name>Bugs Bunny</name> <address>The Rabbit Hole, The Field behind Your House</address> <email>bugs@bunnyplanet.com</email> </item> <item> <name>Batman</name> <address>The Batcave, Gotham City</address> <tel>123 7654</tel> <url>http://www.belfry.net/</url> <email>bruce@gotham-millionaires.com</email> </item> </addressbook>
    Now, in order to convert this XML document into a delimiter-separated file, I need an XSLT stylesheet like this:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <!- Set the "|" symbol as the default delimiter à <xsl:param name="delimiter" select="normalize-space('|')"/> <xsl:template match="/addressbook"> <xsl:for-each select="item"> <xsl:value-of select="normalize-space(name)"/> <xsl:value-of select="$delimiter"/> <xsl:value-of select="normalize-space(address)"/> <xsl:value-of select="$delimiter"/> <xsl:value-of select="normalize-space(tel)"/> <xsl:value-of select="$delimiter"/> <xsl:value-of select="normalize-space(email)"/> <xsl:value-of select="$delimiter"/> <xsl:value-of select="normalize-space(url)"/> <!- hexadecimal value for the new-line character à <xsl:text>&#x0A;</xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>
    And here's the Java code to tie it all together:

    // imported java classes import javax.xml.transform.*; import javax.xml.transform.stream.*; import java.io.*; public class xml2csv { // store the names of the files public static String xmlFile, xslFile, resultFile,delimiterValue = ""; // parameters for the getAssociatedStylesheet() method of the TransformerFactory class // Set them to null as they are not essential here String media = null , title = null, charset = null; public xml2csv(String xmlFile, String resultFile, String delimiterValue) { try { // create an instance of the TransformerFactory class TransformerFactory tFactory = TransformerFactory.newInstance(); // get the name of the stylesheet that has been defined in the XML file. // create a Source object for use by the upcoming newTransformer() method Source stylesheet = tFactory.getAssociatedStylesheet (new StreamSource(xmlFile),media, title, charset); // create a transformer which takes the name of the stylesheet // as an input parameter Transformer transformer = tFactory.newTransformer(stylesheet); // set a delimiter via the setParameter() method of the transformer transformer.setParameter("delimiter",delimiterValue); // perform the transformation transformer.transform(new StreamSource(xmlFile), new StreamResult(resultFile)); System.out.println("Done!"); } catch (TransformerException e) { System.err.println("The following error occured: " + e); } } // everything starts here public static void main (String[] args) { if(args.length != 3) { System.err.println("Please specify three parameters:n1. The name and path to the XML file.n2. The name of the output file.n3. The delimiter to be used."); return; } // set some variables xmlFile = args[0]; resultFile = args[1]; delimiterValue = args[2]; xml2csv mySecondExample = new xml2csv(xmlFile, resultFile, delimiterValue); } }


    Most of the code is identical to the previous example. There are a couple of important differences, though. First, the parameters passed to the constructor are different in this case.

    public xml2csv(String xmlFile, String resultFile, String delimiterValue) { // snip }
    Over here, I'm passing three parameters to the constructor: the name of the XML file, the name of the output file, and the delimiter to be used between the various elements of a record. What about the XSLT file, you ask? Well, that's sourced automatically from the XML file via the getAssociatedStylesheet() method of the TransformerFactory class.

    // create an instance of the TransformerFactory class TransformerFactory tFactory = TransformerFactory.newInstance(); // get the name of the stylesheet that has been defined in the XML file. // create a Source object for use by the upcoming newTransformer() method Source stylesheet = tFactory.getAssociatedStylesheet (new StreamSource(xmlFile),media, title, charset); [/code]

    A new Source object is created to represent this stylesheet; this Source object is ultimately passed to the Transformer class.

    // create a transformer which takes the name of the stylesheet // as an input parameter Transformer transformer = tFactory.newTransformer(stylesheet);
    If you take a close look at the XSLT file above, you'll see that I've defined an XSLT parameter named "delimiter". This parameter is essentially a variable which can be accessed by XSLT, and a value can be assigned to it via the setParameter() method of the Transformer class.

    // set a delimiter via the setParameter() method of the transformer transformer.setParameter("delimiter",delimiterValue);
    In this case, the "delimiter" parameter is set to whatever delimiter was specified by the user.

    Finally, the actual transformation is performed, the output stored in the desired output file, and a result code generated. [code] // perform the transformation transformer.transform(new StreamSource(xmlFile), new StreamResult(resultFile)); System.out.println("Done!");
    Here's what it looks like, assuming you use a pipe (|) as delimiter (I haven't used a comma simply because some of the entries already contain commas):

    Bugs Bunny|The Rabbit Hole, The Field behind Your House||bugs@bunnyplanet.com| Batman|The Batcave, Gotham City|123 7654|bruce@gotham-millionaires.com|http://www.belfry.net/
    Isn't it simple when you know how?

     
     
    >>> More XML Articles          >>> More By icarus, (c) Melonfire
     

       

    XML ARTICLES

    - Flex Array Collection Sort and Filtering
    - The Flex Tree Control
    - Flex List Controls
    - Working with Flex and Datagrids
    - How to Set Up Podcasting and Vodcasting
    - Creating an RSS Reader Application
    - Building an RSS File
    - An Introduction to XUL Part 6
    - An Introduction to XUL Part 5
    - An Introduction to XUL Part 4
    - An Introduction to XUL Part 3
    - An Introduction to XUL Part 2
    - An Introduction to XUL Part 1
    - XML Matters: Practical XML Data Design and M...
    - Practical XML Data Design and Manipulation f...





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 4 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek