Builder http://builder.com.com Presents your XML E-NEWSLETTER for September 4, 2002 <-------------------------------------------> PASS PARAMETERS TO XSL TEMPLATES PROGRAMMATICALLY Imagine you have a list of items in an XML document that you need to display to a user on a Web page. Assume the user needs to select which column they want to sort on and the order of the sort. When it comes to using XSL, this might sound complicated, but it's easier than you think. A SAMPLE ORDER DOCUMENT LISTING 1 shows our simple XML document with three items in it. LISTING 1: order.xml 9900234 1234 5.95 100 595.00 Super Widget Clamp 6234 22.00 10 220.00 Mighty Foobar Flange 9982 2.50 1000 2500.00 Deluxe Doohickie LISTING 2 shows a simple XSL template that will transform our document into HTML. LISTING 2: simple.xsl
SKU Description Price Quantity Subtotal
TRANSLATING WITH JAVA In order to pass parameters to our template programmatically, we'll need to perform our transformation programmatically. We'll use the Apache Software Foundation's Xalan product to process our XSL template. LISTING 3 shows the code we'll use to perform this translation and pass parameters to our template. LISTING 3: MyTransformer.java import javax.xml.transform.*; import javax.xml.transform.stream.*; import java.util.*; import java.io.*; public class MyTransformer { public void transform(Source xml, Source xsl, Result result, HashMap params) throws TransformerException { TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer t = tfactory.newTransformer(xsl); Set s = params.entrySet(); Iterator i = s.iterator(); Map.Entry me; while (i.hasNext()) { me = (Map.Entry) i.next(); t.setParameter((String)me.getKey(), me.getValue()); } t.transform(xml, result); } public Source SourceFromFilename(String filename) { File file = new File(filename); Source source = new StreamSource(file); return source; } public static void main(String[] args) { String xmlFile = "C:\\order.xml"; String xslFile = "C:\\order.xsl"; MyTransformer myt; Source xml; Source xsl; Result result = new StreamResult(System.out); HashMap params = new HashMap(); try { myt = new MyTransformer(); xml = myt.SourceFromFilename(xmlFile); xsl = myt.SourceFromFilename(xslFile); params.put("column", "Quantity"); params.put("order", "descending"); myt.transform(xml, xsl, result, params); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } } } The main method is called when the class is run from the command line. We've hard-coded the names of our order document and our XSL template into this method. Our class includes a simple function for creating new Source objects from files identified by a filename, and we'll use this to pull in our order document and template. Next, we'll use a HashMap object to store the parameters (column and order) we want to pass to our template. The transform method handles the actual XSL translation by creating a Transformer class from the TransformerFactory. The parameters to the translation are sent using the setParameter method of the Transformer class. We'll use an iterator to step through each entry in our HashMap and set the parameters. Each parameter that is set is available to the XSL template, as shown in LISTING 4. The elements at the top of the template identify the incoming parameters and provide default values if the parameters are missing. LISTING 4: order.xsl
SKU Description Price Quantity Subtotal
Brian Schaffner is a senior consultant for Fujitsu Consulting. He provides architecture, design, and development support for Fujitsu's Telcom360 group. ----------------------------------------