Transforming Flat Files To XML With SAX and XSLT, Page 2
Echo Stylesheet
We'll use a very simple stylesheet to output the XML document that corresponds exactly with the SAX events that our parser broadcast. I've decided to call this echo.xsl because the stylesheet simply sounds back the input document. Keep in mind that any stylesheet could be used here. The output XML doesn't have to look anything like the SAX events that it will be receiving. The stylesheet will be "fooled" into thinking that it's dealing with XML even though we're dealing with a non-XML data structure. In an indirect way, the stylesheet becomes your "handler," or recipient of the events broadcast by the parser.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Our "echo" stylesheet is doing a "deep copy." The single template matches on all document nodes. It copies the context node and, recursively, all of its children via the <xsl:apply-templates/>. This type of template can be useful when you would like to make global changes to an XML file.
Transforming a SAX Source With TrAX
public static void main(String[] args) throws Exception
{
// construct SAXSource with our custom XMLReader
InputStream props = ClassLoader.getSystemResourceAsStream
("my.properties");
InputSource inputSource = new InputSource(props);
XMLReader parser = new PropertyFileParser();
SAXSource saxSource = new SAXSource(parser, inputSource);
// construct a transformer using the echo stylesheet
TransformerFactory factory = TransformerFactory.newInstance();
StreamSource xslSource = new StreamSource("echo.xsl");
Transformer transformer = factory.newTransformer(xslSource);
// transform the SAXSource to the result
StreamResult result = new StreamResult("properties.xml");
transformer.transform(saxSource, result);
}
Using the TrAX API, the main() method of our program performs the following steps:
- A SAXSource object is constructed with our PropertyFileParser and an input source representing the property file to parse.
- A transformer object is constructed for our "echo" stylesheet.
- The SAXSource is transformed into a Result object.
Although a StreamResult was used in this example so that we could output a file, the result could have been a DOM or any other type of Result object. Here is the XML that was produced by the transformation:
<?xml version="1.0" encoding="UTF-8"?> <Properties> <Background-Color>White</Background-Color> <Font-Family>Arial</Font-Family> <Font-Size>12pt</Font-Size> <Foreground-Color>Black</Foreground-Color>> </Properties>
Summary
Transforming non-XML data structures into XML is a common problem. Many custom solutions are employed. It's possible to use standard XML APIs to solve this problem. Rather than creating a multiple-step process, we can directly get from our source format to our target XML format. This can result in performance improvements by eliminating unnecessary steps.
We reviewed SAX parsing concepts and learned how to broadcast our own SAX events. We developed a class to transform Java properties files into a stream of XML events. We showed how to use the TrAX API to orchestrate the transformation process using our "echo" stylesheet. By using the technique demonstrated in this article, you can transform virtually any data structure into XML using the power of SAX and XSLT. But the rest is up to you!
Code Examples
To download the sample Java and XSL code, click here.
About the Author
![]() |
Jeff Ryan is an architect for Hartford Financial Services. He has eighteen years of experience designing and developing automated solutions to business problems. His current focus is on Java, XML, and Web Services technology. He may be reached at jryan@thehartford.com. |

