Copyright (c) 1998, 1999 James Clark
See the file copying.txt for copying permission.
XT is an implementation in Java of XSL Transformations. This version of XT implements the PR-xslt-19991008 version of XSLT. Stylesheets written for earlier versions of the XSLT WD must be converted before they can be used with this version of XT.
This should be considered a beta release.
This release of XT adds support for the following:
xt:node-set
extension
function that converts a result tree fragment to a node-setxt:intersection
extension
function that returns the intersection of two node-setsxt:difference
extension
function that returns the difference of two node-setsThis release of XT adds support for the following:
doctype-system
, doctype-public
,
omit-xml-declaration
and standalone
attributes on xsl:output
preceding
axisxsl:message
To use XT, you need:
Locator
information,
otherwise you won't get any line numbers in error messagesPut xt.jar
in your CLASSPATH
, together
with whatever is needed for your XML parser, and sax.jar
if that isn't included with your XML parser. Then use the
command:
java -Dcom.jclark.xsl.sax.parser=your-sax-driver com.jclark.xsl.sax.Driver source stylesheet result name=value...
The name=value
arguments are
optional and specify parameter names and values; they can occur in any
order with respect to the other arguments. They will be ignored
unless the stylesheet contains a corresponding top-level
xsl:param
element. The value of the parameter will be of
type string.
To find a SAX parser, XT first uses the value of the system
property com.jclark.xsl.sax.parser
; if this is not set it
uses the value of the system property org.xml.sax.parser
;
if this is not set it uses the class
com.jclark.xml.sax.CommentDriver
(This subclasses the
normal XP SAX driver to provide support for comments; it is present
only in XP version 0.5 or later; if you have an earlier version of XP
use -Dcom.jclark.xsl.sax.parser=com.jclark.xml.sax.Driver
instead.)
Alternatively under Windows you can use XT packaged as a Win32 executable. This includes XP and SAX. To use this, you will need to have the Microsoft Java VM installed (this is included with IE). Run this with the command:
xt source stylesheet result name=value...
XT can be used as a servlet. This requires a servlet engine that
implements at least version 2.1 of the Java Servlet API. The servlet
class is com.jclark.xsl.sax.XSLServlet
. The servlet
requires an init parameter stylesheet
; the value is the
path of the stylesheet in a form suitable to be passed to
ServletContext.getResource
. The translated path gives
the XML document to be transformed. An extension of .xml
will be automatically added to the translated path if necessary.
(Some browsers assume that a URL ending in .xml
is an XML
document.) Parameters from the query part of the URL are passed in as
parameters to the stylesheet. The stylesheet is cached on
initialization.
The public interface to XT is
com.jclark.xsl.sax.XSLProcessor
which is implemented by
com.jclark.xsl.sax.XSLProcessorImpl
. This interface is
based on SAX.
There is also a simple API based purely on the
DOM. This is com.jclark.xsl.dom.TransformEngine
, which
is implemented by com.jclark.xsl.dom.XSLTransformEngine
.
This is significantly less functional and much slower than the SAX
API. The file DOMDemo.java
in the demo
directory is a demo of this.
It is also possible to mix SAX and the DOM, using the DOM for input
and SAX for output; this requires that a class be created that extends
com.jclark.xsl.dom.XMLProcessorImpl
and implements at
least the load
method. The class
com.jclark.xsl.dom.SunXMLProcessorImpl
does this for
Sun's DOM implementation (in Project X TR2). An object of the class
extending com.jclark.xsl.dom.XMLProcessorImpl
can be
passed to the setParser(XMLProcessorEx)
method of
com.jclark.xsl.sax.XSLProcessorImpl
. XT will be much
slower when using the DOM than when using SAX directly, so you should
not use this unless you already have a DOM tree as a result of some
other processing. For testing purposes, you can use a class extending
com.jclark.xsl.dom.XMLProcessorImpl
with
com.jclark.xsl.sax.Driver
by specifying the name of the
class as the value of the com.jclark.xsl.sax.parser
system property.
The following features of the XSLT PR are not yet implemented:
extension-element-prefixes
and
xsl:extension-element-prefixes
attributes, the
xsl:fallback
element, and the
element-available
function)xsl:key
element, and the key()
function)xsl:decimal-format
element and the optional third
argument on the format-number()
functionnamespace
axisxsl:exclude-result-prefixes
attribute on literal
result elements (the exclude-result-prefixes
attribute
on xsl:stylesheet
is implemented)There are also some known bugs, notably:
node()
node-test does not work in match patterns
(it does work in expressions).document()
function does not pay attention to the
HTTP content-type
header.xsl:import
element does not conform to the
requirement that when xsl:include
is used to include a
stylesheet, any xsl:import
elements in the included
document are moved up in the including document to after any existing
xsl:import
elements in the including document.Apart from missing features and bugs, the implementation is in need of improvement in several areas, including:
xsl:number
element is
slow.xml
output method ignores the
encoding
and cdata-section-elements
attributes on xsl:output
.document()
function does not support fragment
identifiers in URIs for any media typesNot much effort has yet been devoted to optimizing performance.
A call to a function ns:foo
where ns
is bound to a namespace of the form
http://www.jclark.com/xt/java/className
is
treated as a call of the static method foo
of
the class with fully-qualified name
className
. Hyphens in method names are removed
with the character following the hyphen being upper-cased.
Overloading based on number of parameters is supported; overloading
based on parameter types is not. A non-static method is treated like
a static method with the this
object as an additional
first argument. A constructor is treated like a static method named
new
. Extension functions can return objects of arbitrary
types which can then be passed as arguments to other extension
functions or stored in variables.
For example, the following
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://www.jclark.com/xt/java/java.util.Date"> <xsl:template match="/"> <html> <xsl:if test="function-available('date:to-string') and function-available('date:new')"> <p><xsl:value-of select="date:to-string(date:new())"/></p> </xsl:if> </html> </xsl:template> </xsl:stylesheet>
will print out the current date.
Types are mapped between XSLT and Java as follows:
XSLT type | Java type |
---|---|
string | java.lang.String |
number | double |
boolean | boolean |
node-set | com.jclark.xsl.om.NodeIterator |
result tree fragment | com.jclark.xsl.sax.ResultTreeFragment |
On return from an extension function, an object of type
com.jclark.xsl.om.Node
is also allowed and will be
treated as a node-set; also any numeric type is allowed and will be
converted to a number.
The demo
directory has an examples.
XT supports an extension element
xt:document
for creating output documents in
addition to the main output document. The prefix
xt
must be bound to the namespace URI
http://www.jclark.com/xt
.
XT does not yet properly implement the element extension mechanism,
and will recognize the namespace URI
http://www.jclark.com/xt
as an extension namespace
regardless of whether it has been declared using an
extension-element-prefixes
or
xsl:extension-element-prefixes
. You should not rely on
this and should declare the namespace
http://www.jclark.com/xt
as an extension namespace in
accordance with the XSLT WD. For example,
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xt="http://www.jclark.com/xt" extension-element-prefixes="xt"> ... </xsl:stylesheet>
The xt:document
element has a required
href
attribute, which must be a relative URL. The value
of the href
attribute is interpreted as an attribute
value template. The content of the
xt:document
element is a template for the
result tree to be stored in the location specified by the
href
attribute. The base URL for resolving the
href
relative URL is the URL of the parent output
document: either the URL of the main output document or the URL in
which the parent xt:document
element was
stored. Thus, the same relative URL specifed by the href
attribute can be used in the parent document to reference the document
created by the xt:document
element.
The xt:document
element can also have all
the same attributes as the xsl:output
element. These
attributes are merged with attributes specified on top-level
xsl:output
elements to determine the output method for
this document. The attributes on the
xt:document
element take precedence over the
attributes specified on top-level xsl:output
elements.
For example,
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xt="http://www.jclark.com/xt" extension-element-prefixes="xt"> <xsl:variable name="file">out</xsl:variable> <xsl:template match="/"> <xt:document method="xml" href="{$file}.xml"> <xsl:call-template name="out"/> </xt:document> <xt:document method="html" href="{$file}.html"> <xsl:call-template name="out"/> </xt:document> <xt:document method="text" href="{$file}.txt"> <xsl:call-template name="out"/> </xt:document> </xsl:template> <xsl:template name="out"> <html> <head><title>Title</title></head> <body> <p>Line 1<br/>Line 2</p> </body> </html> </xsl:template> </xsl:stylesheet>
The demo
directory has a couple more examples.
XT supports an additional output method of
xt:nxml
where the prefix
xt
is bound to the namespace URI
http://www.jclark.com/xt
. This produces non-XML output
from a result document that conforms to the following DTD:
<!ELEMENT nxml (escape*, (control|data)*)> <!ELEMENT escape (#PCDATA|char)*> <!ATTLIST escape char CDATA #REQUIRED> <!ELEMENT control (#PCDATA|char|data|control)*> <!ELEMENT data (#PCDATA|data|control)*> <!ELEMENT char EMPTY> <!ATTLIST char number NMTOKEN #REQUIRED>
The data
element contains data. Within a
data
element control characters get escaped. The
escape
element specifies how a particular control
character gets escaped.
The control
element contains control information.
Within a control
element, all characters are output
directly without escaping.
The char
element allows the output of a character that
is not allowed by XML (such as control-L).
For example, the following stylesheet
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xt:nxml" xmlns:xt="http://www.jclark.com/xt"/> <xsl:template match="/"> <nxml> <escape char="\">\\</escape> <data>&<>\</data> <control>&<>\</control> </nxml> </xsl:template> </xsl:stylesheet>
will output
&<>\\&<>\
The encoding
attribute on xsl:output
applies to the xt:nxml
output method.
A result method can also have the form
java:class
where
java
is bound to the namespace URI
http://www.jclark.com/xt/java
and class
is
the name of a Java class that implements the
com.jclark.xsl.sax.OutputDocumentHandler
interface (which
extends org.xml.sax.DocumentHandler
). For example,
<xsl:output method="xtj:com.jclark.xsl.sax.NXMLOutputHandler" xmlns:xtj="http://www.jclark.com/xt/java"/>
is equivalent to
<xsl:output method="xt:nxml" xmlns:xt="http://www.jclark.com/xt"/>
XT provides the following built-in extension functions. The
namespace URI for these is http://www.jclark.com/xt
.
xt:node-set
sort-uniq
example in the
demo
directory.xt:intersection
xt:difference
Please report bugs to me. When reporting bugs please be sure to include both a complete stylesheet and complete source document that illustrate the bug. Create a zip file containing all the necessary files, and attach the zip file to your email.
James Clark