I've already posted this code to the list, but 
will do it again.  I would like to see it finding 
its place on http://xml.apache.org/fop/embedding.html
one day - shouldn't we promote efficient use of FOP 
instead  of giving an example of embedding, which is 
technically correct but hardly userful for servlet 
developers?

The code below has the following benefits compared to
Jim's example:
  - all transformations are done in a single pass
    by chaining SAX events
  - the resulting PDF is not stored in memory, but
     streamed directly into the output stream
    (in Jim's example, it is first stored in a string,
     then converted to byte array, and only then is
     writted to the output stream)



import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import org.apache.fop.apps.Driver;

// -------
// 1. Get a Source for XML document
// -------

 // a) from string
Source strSource = new StreamSource(new StringReader(xmlString));

 // b) from file
Source fileSource = new StreamSource(xmlFile);

 // c) from JDOM Document 
Source domSource = new org.jdom.transform.JDOMSource( jdomDocument )

// -------
// 2. Get stylesheet transformer
// -------
 // from file, see above examples for other types of XSL input
Templates template = transformerFactory.newTemplates( new StreamSource(
xslFile ));
 // note - template object is multi-threaded and should be cached if you
plan
 // to use the same XSL repeatedly
Transformer transformer = template.mewTransformer();

// -------
// 3. Create FOP driver and set rendering mode and output stream
// -------
Driver driver = new Driver();
driver.setRenderer(driver.RENDER_PDF);
driver.setOutputStream( response.getOutputStream() );
// initialize logger - see sample code on FOP website
driver.setLogger(logger);

// -------
// 4. Create SAXResult based on FOP Driver content handler 
// which will accept SAX events and build FOP tree
// -------
Result saxResult = new SAXResult( driver.getContentHandler() );

// 5. Use the Transformer to transform an XML Source and 
// send the output to a Result object. Implicitely it will 
// create the FOP tree by firing SAX events.
transformer.transform( whateverSource, saxResult );

// 6. Your user is already viewing the PDF!
response.getOutputStream().flush();
response.getOutputStream().close();

Yuri Shkuro
HR - Information Technology
Goldman Sachs & Co., New York

-----Original Message-----
From: Jim Urban [mailto:[EMAIL PROTECTED]]
Sent: Monday, November 12, 2001 2:08 PM
To: [EMAIL PROTECTED]
Subject: RE: Question on XSLTInputHandler


Here is a block of code our of one my servlets. This code takes a string
containing XML, applies an XSL:FO style sheet to it, and runs the XML:FO
through FOP and send s the PDF directly back to the browser.

Writer      out             = new StringWriter();
Transformer pdfTransformer  =
NsTransformerCollection.loadTransformer("my.xsl");;
String xmlString = .....
Source      xmlSource  = new StreamSource(new StringReader(xmlString));
pdfTransformer.transform(xmlSource, new StreamResult(out));
out.close();
String fopstring = out.toString();
InputSource foSource = getInput(fopstring);
try
{
 ByteArrayOutputStream out = new ByteArrayOutputStream();
 uResponse.setContentType("application/pdf");
 Driver driver = new Driver(iInputSource, out);
 driver.setRenderer(Driver.RENDER_PDF);
 driver.run();
 byte[] content = out.toByteArray();
 uResponse.setContentLength(content.length);
 uResponse.getOutputStream().write(content);
 uResponse.getOutputStream().flush();
 uResponse.flushBuffer();
}
catch (Exception e){}

Jim


-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]
Sent: Monday, November 12, 2001 12:49 PM
To: [EMAIL PROTECTED]
Subject: Question on XSLTInputHandler


Hello,

I've looked at the example servlet and found that the XSLTInputHandler
takes as input a java.io.File. However, I am constructing the XML
document dynamically and have it as a java.lang.String in memory. It
seems unnecessary I/O to write it out to a temporary file, just to pass
it to the XSLTInputHandler. Looking at the source of
XSLTInputHandler.java I didn't find any alternate way to call it. What
would the recommended procedure be in this case, where I already have
the XML document in memory?

thanks in advance for any pointers,

Ulrich

--
Ulrich Mayring
DENIC eG, Systementwicklung


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to