Doing the XML Transformation
Now I'll actually use the JAXP parser I've just created in a transformation. In order to do any type of transformation you need two things: an XML file and an XSL file. The XML file is what you want to transform from and the XSL tells the XSLT engine how to transform it. This parser creates a DOM tree that outputs directly to XML, so you don't actually need the XSL file. However, there could be instances in which you'd want to transform the DOM tree into another XML format. With that in mind, I am going to create a command-line application that takes an input filename as a parameter and, optionally, an XSL filename.
if(args.length == 0)
System.err.println("Usage: java " +
Processor.class.getName() + " <data file> [xslt file]");
String dataFile = args;
The above code checks to see if the application was run without any parameters and, if so, prints out usage information. Once the user successfully supplies a filename for the input data file, you set the String dataFile to its value. Next, create an instance of the SAXTransformerFactory class.
SAXTransformerFactory saxTransFact = (SAXTransformerFactory)
TransformerHandler transHand = null;
I need the TransformerHandler constructor because it will handle the instruction to use an XSL file for the transformation, if one is provided. It can optionally take a StreamSource as an argument.
if(args.length > 1)
transHand = saxTransFact.newTransformerHandler
(new StreamSource(new File(args)));
transHand = saxTransFact.newTransformerHandler();
This code checks to see if an XSL file was specified from the command-line, and if so, passes a new StreamSource instance to the TransformerHandler.
XMLReader reader = null;
The TransformerHandler also needs to know where to stream its results. In this case I have chosen to use System.out, but any stream would work just fine. Now I need to create an instance of the parser. To make the code more generic, I cast whatever parser I instantiate down to the XMLReader interface.
reader = (XMLReader) new CSVReader();
reader = (XMLReader) new PipeReader();
System.err.println("Invalid file extension");
InputSource is = new InputSource(new FileReader(dataFile));
The above logic block simply looks at the file extension of the input data file to determine which parser to use. If it can't match up an extension with a parser, it simply prints an error and exits the program. After creating an instance of an XMLReader I create a new InputSource using the data file.
I then pass my TransformerHandler to my XMLReader as the ContentHandler. All that is left to do is actually call the parse method, which takes an InputSource as a parameter. And, finally, print out an extra blank line for good measure.
The parser I created in this tutorial reads legacy data files and creates a DOM representation of them. I created a very simple program to do an XML transformation based on this DOM. I then used this program to test the legacy data parsers I created. I could have focused simply on the transformation code, but I thought a proper way to introduce JAXP was to show how it can be used to do useful, if unexpected, new things.