futureLAB JSP Tag Library - Style Tag
Marc Liyanage
Software Engineer
futureLAB AG
$Id: tag_style.docbook,v 1.4 2003/07/27 12:09:16 mliyanage Exp $
This custom action is used to transform a piece of XML code
contained in the tag's body using an XSLT style sheet.
We know of two other tags in the
jakarta-taglibs
project which do the same, but both had various issues like the inability
to nest properly, inability to resolve relative <xsl:include>
references, lack of transformation object caching mechanism or
the use of old, deprecated APIs.
So here's our own implementation that relies only on
the most recent JAXP and TrAX APIs.
Style tags can be nested. You can use this to transform some
XML into an intermediate format, and then enclose the result within
another style tag to apply a second transformation to the intermediate format.
This kind of nesting can be arbitrarily deep.
Can take a javax.xml.transform.Transformer object as input for
the transformation. This object should ideally be produced by a
javax.xml.transform.Template object that is cached in the
application or session scope, resulting in good performance.
Using a filename as XSLT source
This first method is the most convenient one. Starting with version 1.4 of the tag library,
it also performs very well because there is now a caching mechanism which will
compile the stylesheets once and store the compiled form (a JAXP Templates object) into an
application scope attribute (ServletContext attribute "ch.futurelab.jsptags.xsltcache") when the
style tag is used for the first time. On each subsequent invocation, it will compare the file
modification date on disk to the one stored in memory and it will re-use the existing,
pre-compiled one if the dates match, and reload and re-compile from the file on disk otherwise.
<fl:style xsltfilename="/data/www/mywebsite.com/mystylesheet.xsl">
<blah>
<somedata>...</somedata>
</blah>
</fl:style>
|
|
| Example 1. Using a filename as XSLT source |
|
Using a javax.xml.transform.Source as XSLT source
This method performs best if a DOMSource
is used because the stylesheet does not need to be parsed into a DOM tree again.
<%@ page import="org.w3c.dom.*" %>
<%@ page import="javax.xml.transform.dom.*" %>
<%@ page import="javax.xml.parsers.*" %>
<jsp:useBean
id="domSourceBean"
class="javax.xml.transform.dom.DOMSource"
scope="application"
>
<%
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document xsltDoc = db.parse("file:///data/www/mywebsite.com/mystylesheet.xsl");
%>
<jsp:setProperty name="domSourceBean" property="node" value="<%= xsltDoc %>"/>
</jsp:useBean>
<fl:style xsltsource="<%= domSourceBean %>">
<blah>
<somedata>...</somedata>
</blah>
</fl:style>
|
|
| Example 2. Using a javax.xml.transform.Source as XSLT source |
|
Using a javax.xml.transform.Transformer as XSLT source
This method has the best performance if the Transformer is
coming from a persistent javax.xml.transform.Templates
object in the application scope.
<jsp:useBean
id="myApplicationBean"
class="my.very.own.ApplicationBean"
scope="application"
>
...
</jsp:useBean>
<fl:style xslttransformer="<%= myApplicationBean.getTransformer() %>">
<blah>
<somedata>...</somedata>
</blah>
</fl:style>
|
|
| Example 3. Using a javax.xml.transform.Transformer as XSLT source |
|
Here the result of one transformation, together with some additional data,
is used as input for a second transformation.
<fl:style xsltfilename="/data/www/mywebsite.com/the_outer_stylesheet.xsl">
<moredata>
...
</moredata>
<fl:style xsltfilename="/data/www/mywebsite.com/the_inner_stylesheet.xsl">
<blah>
<somedata>...</somedata>
</blah>
</fl:style>
</fl:style>
|
|
| Example 4. Nesting transformations |
|
This section provides a detailed list of the various attributes for this tag.
All of them accept run-time values, i.e. you can,
and usually have to, use the <%= ... %>
construct in the attribute value.
| Attribute name | Description | Default | Mandatory |
|---|
| xsltfilename | A string containing the filesystem path of an XSLT stylesheet file
to use for the transformation. The system will prepend "file://"
to it and create a new StreamSource with the resulting string. | - | One of xsltfilename, xsltsource or xslttransformer is mandatory | | xsltsource | An object that implements javax.xml.transform.Source,
to be used as the stylesheet for the transformation. Useful if you already have an
existing source object in your code. Note: If you use a DOMSource, you have to invoke
setNamespaceAware(true) on the
DocumentBuilderFactory which is used to create the parser
that builds the DOM tree. Otherwise you will get an error regarding a missing
version number during the transformation. Note 2: If you use xsl:include or
xsl:import directives with relative paths in your
stylesheets, you will have to call setSystemId()
with the base path on the source objects.
The XSLT processor will not be able to resolve the relative references otherwise. | - | | xslttransformer | An existing instance of javax.xml.transform.Transformer,
to be used for the transformation. | - | | omitxmldeclaration | A string indicating if the xml declaration should be omitted
when inserting the output of the transformation back into the document. This is needed when the output is wrapped by other XML elements which
are written into the JSP code by hand. The XML declaration string would be
invalid in this case because it wouldn't be at the start of the document. Valid values are "yes" and "no". | yes | No | | inputencoding | A string with the encoding of the XML input. Valid values are the ones which are used in the Java libraries, like
"ISO-8859-1" or "UTF-8". | ISO-8859-1 | No | | outputencoding | A string containing the desired encoding of the transformation
output which is put back into the JSP Page. Valid values are the ones which are used in the Java libraries, like
"ISO-8859-1" or "UTF-8". | ISO-8859-1 | No |
|
| Table 1. Attributes for the style tag |
|