Stylus Studio® Converters Unleashed

By: Ivan Pedruzzi, Product Architect, The Stylus Studio® Team.

If you have processed XML using Java, you should be familiar with JAXP (Java API for XML Processing). Here is a simple program that processes an XML document using XSLT:

import javax.xml.transform.*;
public class MyTransform {
public static void main(String args[]) throws Throwable
   {
      StreamSource input = new StreamSource("file:///c:/input.xml");
      StreamSource xslt = new StreamSource("file:///c:/tranform.xsl");
      StreamResult output = new StreamResult("file:///c:/result.xml");
      TransformerFactory tf = TransformerFactory.newInstance();
      tf.newTransformer(xslt).transform(input, output);
   }
}

Nice and easy if you are dealing with XML documents, but what happens if your data is not all XML? Assume for instance that we need to exchange data with a business partner who requires files using a specific XML dialect, but that our data is tabular and is stored as CSV files.

Accessing Non-XML Files as XML in Java

Here's a sample from our CSV file of used motorcycles inventory:

make,model,year,mileage
BMW,R1150RS,2004,14274
Kawasaki,GPz1100,1996,60234
Ducati,ST2,1997,24000
Moto Guzzi,LeMans,2001,12393
BMW,R1150R,2002,17439
Ducati,Monster,2000,15682
Aprilia,Futura,2001,17320

Our partner requires an XML document that looks like what follows, and has provided an XML Schema so that we can ensure that the XML we provide complies with his requirements:

<?xml version="1.0"?>
<inventory>
   <bike>
      <make>BMW</make>
      <model>R1150RS</model>
      <year>2004</year>
      <mileage>14274</mileage>
   </bike>
</inventory>

The first step is simply to create an XML representation of our CSV data.

<?xml version="1.0"?>
<table>
   <row>
      <make>BMW</make>
      <model>R1150RS</model>
      <year>2004</year>
      <mileage>14274</mileage>
   </row>
   <row>
      <make>Kawasaki</make>
      <model>GPz1100</model>
      <year>1996</year>
      <mileage>60234</mileage>
   </row>
   <row>
      <make>Ducati</make>
      <model>ST2</model>
      <year>1997</year>
      <mileage>24000</mileage>
   </row>
   <row>
      <make>Moto Guzzi</make>
      <model>LeMans</model>
      <year>2001</year>
      <mileage>12393</mileage>
   </row>
   <row>
      <make>BMW</make>
      <model>R1150R</model>
      <year>2002</year>
      <mileage>17439</mileage>
   </row>
   <row>
      <make>Ducati</make>
      <model>Monster</model>
      <year>2000</year>
      <mileage>15682</mileage>
   </row>
   <row>
      <make>Aprilia</make>
      <model>Futura</model>
      <year>2001</year>
      <mileage>17320</mileage>
   </row>
</table>

Though some of the specifics vary (additional parent elements, different element names, and so on), because the data is now in XML format, XSLT can be used to create the final XML result.

So, that's the theory (CSV to> XML to> XSLT to> XML), but how do you make it all work? Even assuming you have an XML document that represents data stored in CSV format, the prospect of writing XSLT can be daunting. It might sound intimidating, but using Stylus Studio® we can create solid, complex, bug-free XSLT in just a few steps.

  • Create a new XSLT Mapper document. The XSLT Mapper generates XSLT code based on the maps you draw between source and target documents.
  • Use the inventory CSV file as the XSLT source. Stylus Studio® lets us convert it to XML on the fly by selecting user-defined or built-in converters, as shown here:

Selecting an XML Converter

  • Use the XML schema representing the XML format required by our partner as target
  • Create a map between the relevant elements in the converted CSV source and the XML Schema using simply drag-and-drop
  • Click Preview Result to view the XML document that results from processing the XML document (converted from CSV) with the XSLT stylesheet we designed in the XSLT Mapper

You know what they say ... a picture is worth 1000 words.

CSV to XML Mapping

Stylus Studio® did most of the work for us — converting CSV to XML, writing XSLT code based on simple mappings — but what happens if we need to perform the same steps periodically, perhaps as part of larger application so that we can automate the process of exchanging inventory information with our partner? The answer lies in common URLs, and Stylus Studio®'s uncommon Java runtime library.

Automating Non-XML Data Access in Java Applications

URL stands for Uniform Resource Locator. URLs allow us to use a symbolic name to reach a document that either exists somewhere or gets created dynamically when the address represented in the URL is hit. If you look closely inside the Stylus Studio® Project window, you quickly realize how converters work — an converter is represented as a URL, like FTP, HTTP, FILE, and so on.

Browsing XML Converters in Stylus Studio®

Let's take a closer look at an converter's components, using the following converter as an example:

converter:CSV:newline=crlf:sep=,:first=yes:escape=\:quotes='"?file:///c:/one.csv

  • converter: URLs always start with a scheme like HTTP. Stylus Studio® recognizes a special type of URL, one that uses converter as its scheme.
  • CSV: Defines the converter we want to invoke.
  • newline=crlf:sep=,:first=yes:escape=\:quotes='": Parameters are specific to individual converters. For instance, in our CSV converter, first=yes instructs Stylus Studio® to use the first row of the CSV file as list column titles, which in turn are used to provide element names in the final XML document.
  • ?file:///c:/one.csv The name and location of the input file, specified as a URL, that we want to convert. If the converter URL was universally understood by the Java URL class, we could use it as we would any other URL (like http://www.stylusstudio.com/press/news.rss, for example).

Using The Stylus Studio® Runtime Library

Let's go back to the original JAXP example. Wouldn't it be cool if we could use the converter URL to specify the argument for the Java StreamSource method — that is, to effectively use a CSV file as a source for an XSLT transformation, and do it all programmatically? Thanks to the Stylus Studio® runtime library, we can!

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

// here, we have included the Stylus Studio® runtime library
import com.exln.stylus.io.*;

public class MyTransform {
   public static void main(String args[]) throws Throwable
   {
   // we use the createSource method from the Stylus Studio® runtime
   // library, which understands the Stylus Studio® converter URL
   // syntax
   StreamSource input = StylusFileFactory.createSource
      ("converter:CSV:newline=crlf:sep=,:first=yes:escape=\\:quotes='\"?       file:///c:/one.csv", "", true);
   StreamSource xslt = new StreamSource("file:///c:/tranform.xsl");
   StreamResult output = new StreamResult("file:///c:/result.xml");
   TransformerFactory tf = TransformerFactory.newInstance();
   tf.newTransformer(xslt).transform(input, output);
   }
}

JAXP defines a clever mechanism that allows XSLT processors to delegate URL resolution to an external component called the URIResolver. The XSLT processor invokes the URIResolver to turn a URL used in document(), xsl:import, or xsl:include instructions into a Source object.

The StylusFileFactory class in the Stylus Studio® runtime library implements the URIResolver interface, allowing converter URLs to be resolved in the same fashion as standard URLs. Here is an XSLT fragment that shows how a CSV file is accessed as an XML document through the document() function:

<xsl:for-each select="document('    converter:CSV:newline=crlf:sep=,:first=yes:
   escape=\:quotes='"?file:///c:/one.csv')/table/row">
   <xsl:copy-of select="."/>
</xsl:for-each>

To register a URIResolver, we use the following code:

TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer(xslt);
t.setURIResolver(StylusFileFactory.getFactory());
t.transform(input, output);

We hope you enjoyed this overview of Stylus Studio®'s runtime library. Happy Java programming!

Ivan Pedruzzi,
The Stylus Studio® Team

PURCHASE STYLUS STUDIO ONLINE TODAY!!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

What's New for Stylus Studio® X16?

New XQuery & Web Services Tools, Support for MySQL, PostgreSQL, HL7 EDI, Microsoft .NET Code Generation and much more!

Why Pay More for XML Tools?

With Stylus Studio® X16 XML Enterprise Suite, you get the most comprehensive XML tool suite at one incredibly low price. Value: it's just one of many reasons why smart XML developers are choosing Stylus Studio!

 
Free Stylus Studio XML Training: