> I have an application which currently will transform a Vector
> of Document objects out to HTML files. We would like to be able
> to modify this application to allow the process to create PDF files
> instead of HTML files.
> I have been looking for a way to pipe the output of my Transformer
> into the Input of the FOP Driver object. Unfortunately, I have been
> unable to see any way of doing this except to persist the Transformer
> output to file and then provide this file to the FOP Driver object.
> Could anyone point me in the right direction of how I could transform
> my XML to PDF without creating an intermediate file?

I'd implement an XMLReader. See the link below for a tutorial. Well, the
example is based on a file so you can use a normal InputSource object.
But you can easily extend InputSource to provide access to an object,
such as your Vector of Document objects. 

From the JAXP tutorial:

public class JobSubmissionInputSource extends InputSource {

    private JobSubmission submission;

    public JobSubmissionInputSource(JobSubmission submission) {
        this.submission = submission;

    public JobSubmission getJobSubmission() {
        return this.submission;

In your XMLReader class you will have something like the following:
public class AbstractJobSubmissionReader extends XMLReader {


    public void parse(InputSource input) throws IOException, SAXException {
        if (input instanceof JobSubmissionInputSource) {
        } else throw new SAXException(this.getClass().getName()+" can only work 
with JobSubmissionInputSource");

    public void parse(JobSubmissionInputSource input) throws IOException, 
SAXException {
        JobSubmission submission = input.getJobSubmission();
        //...generate SAX events...

The cool thing is that you don't have to generate HTML or XSL:FO
directly. You can just output what's in your object. To get it running
you have to create a javax.xml.transform.Source object as indicated

public static Source createSourceForJobSubmission(JobSubmission submission) {
   return new SAXSource(new JobSubmissionReader(), new 

You can use that now, to initiate an XSLT transformation (your XML to
XSL:FO) and make sure FOP receives the SAX events. This is done by
getting the ContentHandler from FOP (driver.getContentHandler()). 

        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer trans = factory.newTransformer(new 
        Source src = createSourceForJobSubmission(submission);
        Result res = new SAXResult(driver.getContentHandler());
        trans.transform(src, res);

Of course, you also have to do the usual stuff like setting the
OutputStream for the target file etc.

Granted, this may not be the easiest solution, but it's likely the best
since you can use your ObjectReader (as I call it) for various other things
like just writing out the XML generated by the ObjectReader to a file:

        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer trans = factory.newTransformer(/*identity transform,
        no stylesheet*/);
        Source src = createSourceForJobSubmission(submission);
        Result res = new StreamResult(myxmlfile);
        trans.transform(src, res);

I hope it helps.

Jeremias Märki


Postfach 3954 - Rhynauerstr. 15 - CH-6002 Luzern
Fon +41 41 317 20 20 - Fax +41 41 317 20 29
Internet http://www.outline.ch

Reply via email to