XT

Version 19991105

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.

Changes from Previous Releases

Changes in this release

This release of XT adds support for the following:

Changes in version 19991102

This release of XT adds support for the following:

Usage

To use XT, you need:

Put 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...

Servlet Usage

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.

XT API

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.

Limitations

The following features of the XSLT PR are not yet implemented:

There are also some known bugs, notably:

Apart from missing features and bugs, the implementation is in need of improvement in several areas, including:

Not much effort has yet been devoted to optimizing performance.

Extension Functions

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 typeJava type
stringjava.lang.String
numberdouble
booleanboolean
node-setcom.jclark.xsl.om.NodeIterator
result tree fragmentcom.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.

Multiple Output Documents

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.

Non-XML output

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>&amp;&lt;&gt;\</data>
<control>&amp;&lt;&gt;\</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"/>

Built-in Extension Functions

XT provides the following built-in extension functions. The namespace URI for these is http://www.jclark.com/xt.

xt:node-set
Converts a result tree fragment to the equivalent node-set. The argument must be a node-set or a result tree fragment; the result will be a node-set. See the sort-uniq example in the demo directory.
xt:intersection
Returns the intersection of two node-sets.
xt:difference
Returns the difference of two node-sets (the nodes in the first node-set that are not in the second node-set).

Reporting Bugs

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