| ======================================================================= |
| CONTENTS OF THIS DOCUMENT: |
| |
| o) HOW TO PROVIDE XSL TRANSFORMATIONS AS A WEB SERVICE |
| o) HOW TO INVOKE TRANSLETS FROM A SERVLET |
| o) BUILDING YOUR OWN DOM CACHE |
| |
| ----------------------------------------------------------------------- |
| HOW TO PROVIDE XSL TRANSFORMATIONS AS A WEB SERVICE |
| |
| With XSLTC, XSL transformations can be run from within a servlet. |
| This sample code demonstrates how that can be implemented. |
| |
| The CompiledEJB and CompiledBrazil sample code demonstrate other |
| aproaches to providing XSL transformations as a web service. |
| |
| ----------------------------------------------------------------------- |
| HOW TO INVOKE TRANSLETS FROM A SERVLET |
| |
| The CompiledServlet directory contains the example source code: |
| |
| TransformServlet.java |
| |
| This file contains a minimal implementation of an XSL transformation |
| servlet. It utilizes a cache to store the DOM trees for frequently |
| accessed XML documents. These are not W3C DOM objects; They are |
| specialized DOMs, native to XSLTC and optimzed for use with compiled |
| translets. In addition to the initial input XML documents, the cache |
| may contain DOMs for other XML input documents the translet requires |
| at runtime, when the xsl:document() function is used in the stylesheet. |
| |
| Here's the essential code in the servlet for doing the transformation: |
| |
| // Get a reference to the translet class |
| Class cls = Class.forName(transletName); |
| |
| // Instanciate a translet object (inherits AbstractTranslet) |
| AbstractTranslet translet = (AbstractTranslet)cls.newInstance(); |
| |
| // The translet needs a reference to the cache in case |
| // in needs to load additional XML documents. |
| translet.setDOMCache(cache); |
| |
| // Get the DOM from the DOM cache if current, otherwise |
| // build and cache the DOM first |
| DOMImpl dom = cache.retrieveDocument(documentURI, 0, translet); |
| |
| // Create output handler (you can plug in your own) |
| DefaultSAXOutputHandler saxHandler; |
| saxHandler = new DefaultSAXOutputHandler(out); |
| |
| // Start the transformation |
| translet.transform(dom, new TextOutput(saxHandler)); |
| |
| ----------------------------------------------------------------------- |
| BUILDING YOUR OWN DOM CACHE |
| |
| The interface for the DOM cache consists of a single method, |
| and its definition can be found in: |
| |
| org/apache/xalan/xsltc/DOMCache.java |
| |
| The method contained in the interface is: |
| |
| public DOMImpl retrieveDocument(String uri, |
| int mask, |
| Translet translet); |
| |
| The responsibilities of this method are: |
| |
| A) Build new a DOMImpl and DTDMonitor for XML documents |
| that are not already in the cache: |
| |
| // Instanciate a DOMImpl object |
| Parser parser = new Parser(); |
| DOMImpl dom = new DOMImpl(); |
| // Set URI for imports, includes, and document() functions |
| dom.setDocumentURI(uri); |
| parser = factory.newSAXParser(); |
| reader = parser.getXMLReader(); |
| reader.setContentHandler(dom.getBuilder()); |
| |
| // Use a DTDMonitor to track ID references in DTD |
| DTDMonitor dtdMonitor = new DTDMonitor(); |
| dtdMonitor.handleDTD(reader); |
| |
| // Parse the input document and build DOM |
| reader.parse(uri); |
| |
| At this point the DOMImpl and DTDMonitor objects are |
| populated with the necessary data. The two objects |
| are ready to be put in the cache (using the URI as |
| the lookup key). |
| |
| B) For each time a new document is requested by a translet: |
| |
| // Expand translet's index array to fit this DOM |
| translet.setIndexSize(dom.getSize()); |
| |
| // Build indices for this DOM's DTD's ID references |
| dtdMonitor.buildIdIndex(dom, mask, translet); |
| |
| // Pass unparsed entity URIs to the translet |
| translet.setUnparsedEntityURIs(dtd.getUnparsedEntityURIs()); |
| |
| Step A) must be done every time a document is read into the |
| cache, and step B) every time a document is given to a |
| translet. |
| |
| The XSLTC package contains an example implementation of a |
| DOM cache, based on a very simple round-robin caching |
| algorithm: |
| |
| org/apache/xalan/xsltc/dom/DocumentCache.java |
| |
| ----------------------------------------------------------------------- |
| DOING TRANSFORMATIONS WITHOUT A DOM CACHE |
| |
| Alternatively, you can program a servlet to perform the same basic |
| steps as the XSLTC command-line tool |
| |
| org.apache.xalan.xsltc.cmdline.Transform |
| |
| as follows: |
| |
| |
| // Obtain a reference to the translet class |
| Class cls = Class.forName(transletName); |
| // Instanciate a translet object (inherits AbstractTranslet) |
| AbstractTranslet translet = (AbstractTranslet)cls.newInstance(); |
| |
| // Prepare the internal DOM tree |
| final DOMImpl dom = new DOMImpl(); |
| dom.setDocumentURI(inputURI); |
| |
| // Create a parser for the input document |
| // org.apache.xalan.xsltc.runtime.Constants sets NAMESPACE_FEATURE |
| final SAXParserFactory facory = SAXFactory.newInstance(); |
| try { |
| factory.setFeature(NAMESPACE_FEATURE,true); |
| } |
| catch (Exception e) { |
| factory.setNamespaceAware(true); |
| } |
| parser = factory.newSAXParser(); |
| reader = parser.getXMLReader(); |
| reader.setContentHandler(dom.getBuilder()); |
| |
| // Create a DTDMonitor for handling ID references in the DTD |
| DTDMonitor dtdMonitor = new DTDMonitor(); |
| dtdMonitor.handleDTD(reader); |
| |
| // Create output handler (you can plug in your own) |
| DefaultSAXOutputHandler saxHandler; |
| saxHandler = new DefaultSAXOutputHandler(out); |
| |
| // Parse the document and build the internal DOM |
| reader.parse(inputURI); |
| |
| // Pass information on id/key indicies to the translet |
| translet.setIndexSize(dom.getSize()); |
| dtdMonitor.buildIdIndex(dom, 0, translet); |
| translet.setUnparsedEntityURIs(dtdMonitor.getUnparsedEntityURIs()); |
| |
| // Start the transformation |
| translet.transform(dom, new TextOutput(saxHandler)); |
| |
| |
| ------------------------------------------------------------ |
| END OF README |