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



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.


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


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


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.


Perform the conversion by invoking Converter.convert.