3. Converting an XML document to RTF

This second sample consists in three steps:

  1. Compile the XSLT style sheet for all subsequent uses.

  2. Invoke the XSLT engine to convert the input XML document to XSL-FO.

  3. Invoke XMLmind XSL-FO Converter to convert the temporary XSL-FO file generated by second step to RTF.

Excerpts of samples/java/Sample2.java:

import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.Templates;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.InputSource;
import com.xmlmind.fo.converter.OutputDestination;
import com.xmlmind.fo.converter.Converter;

...

            TransformerFactory factory = TransformerFactory.newInstance();
            Templates compiledStylesheet =
                factory.newTemplates(new StreamSource(xslFile));1

            Transformer transformer = compiledStylesheet.newTransformer();
            foFile = File.createTempFile("sample2_", ".fo");
            transformer.transform(new StreamSource(xmlFile),2
                                  new StreamResult(foFile));

            Converter converter = new Converter();3
            converter.setProperty("outputFormat", "rtf");
            converter.setProperty("outputEncoding", "Cp1252");
            converter.setProperty("imageResolution", "72");
            converter.setProperty("baseURL", xmlFile.toURI().toASCIIString());4

            InputSource src = new InputSource(foFile.toURI().toASCIIString());
            OutputDestination dst = new OutputDestination(rtfFile.getPath());
            converter.convert(src, dst);5

...

1

Compile the XSLT style sheet.

About the thread safety of XMLmind XSL-FO Converter

A Converter instance must not be shared by different threads. In the above code, only the Templates object can be shared between different threads. Transformer and Converter instances cannot.

2

Transform the XML input file to a temporary output file created in the system-dependant temporary file directory (e.g. /tmp on Unix).

3

Create and parameterize a Converter object as explained in Section 2, “Converting an XSL-FO file to RTF”.

4

Setting the baseURL property to the URL of the XML input file is really needed in our case:

If the XML input file references graphics files using relative URLs (example: images/screenshot1.png), then the generated XSL-FO file is likely to contain fo:external-graphic objects referencing the same graphics files using the same relative URLs. The problem is that, in our case, the XSL-FO file is not generated in the same directory as the XML input file. Therefore, without the baseURL property, these relative URLs would be resolved incorrectly by XMLmind XSL-FO Converter.

An advanced alternative to specifying a baseURL property, is to specify an UriResolver object using Converter.setUriResolver.

5

Perform the conversion by invoking Converter.convert.