Saxon XSLT implements the XSLT 1.0 and XPath 1.0 Recommendations from the World Wide Web Consortium, found at http://www.w3.org/TR/xslt and http://www.w3.org/TR/xpath, which are referred to here collectively as "XSLT"
Saxon is 100% conformant to the mandatory requirements of these recommendations, except in some cases where incompatibilities have been introduced in the XSLT 2.0 and XPath 2.0 working drafts.
This release of Saxon implements many facilities defined in the draft XSLT 2.0 specification. This specification is not yet complete, though most features defined in the working draft of 2 May 2003 are available.
Known restrictions include the following:
The xsl:schema-import
declaration is not implemented; and therefore,
it is not possible to refer to user-defined types.
There is no support for source documents, result documents, or temporary trees to be validated and annotated using a schema processor. (But elements and attributes that have a simple built-in type, for example xs:date, can be annotated as such).
The new XSLT 2.0 facility for initiating a transformation by specifying a named template as the entry point is not implemented.
The href
attribute on xsl:result-document
is mandatory.
The new xsl:output
option normalize-unicode
is not implemented.
The xhtml
output method does not follow all the rules for XHTML formatting in
the draft XSLT 2.0 specification.
If key()
is called in a match pattern, the argument must be a string literal.
Keys do not work properly when the key value is anything other than a string.
The semantics of patterns when applied to nodes in non-document trees are not yet properly implemented.
When attributes or other simple-valued nodes are constructed, non-text nodes in the result of the sequence constructor are ignored with a warning (as in 1.0). They should be atomized.
The xsl:perform-sort
element must currently have a select attribute and empty
content (apart from the xsl:sort elements themselves).
When the source document is supplied as a pre-built tree (in any format), Saxon strips whitespace
text nodes as requested by the stylesheet, but takes no account of any xml:space
attributes present in the tree.
This release of Saxon implements
the full XPath 2.0 grammar as defined in the working draft of 22 August 2003, with the exception of schema-related
aspects of the SequenceType
production. The SequenceType production currently allows either generic
types such as item()
or node()
,
a node-kind (e.g. element()
, attribute()
, document-node()
),
a built-in simple schema type (e.g. xs:integer
, xs:date
, xs:ID
),
the types xdt:untypedAtomic
or xdt:anyAtomicType
, or the
constructs "element(*,T)" and "attribute(*,T)" where T is a built-in simple schema type. Note
that the latter require the type annotation of the node to be T, this can be set using the type
attribute of xsl:element and xsl:attribute.
The restrictions in XPath 2.0 support include the following:
Saxon supports the following data types: string, boolean, decimal, duration, integer, float,
double, date, dateTime, time, anyURI, QName, gYear, gYearMonth, gMonth, gMonthDay, gDay,
with their literal forms and constructors. All built-in subtypes of
integer are implemented (but note, unsignedLong does not support values greater than the maximum
value of a Long). All built-in types derived by restriction from xs:string are implemented (but not
the list types IDREFS, NMTOKENS, and ENTITIES). The data types yearMonthDuration, dayTimeDuration,
untypedAtomic, and anyAtomicType are available in the namespace http://www.w3.org/2003/11/xpath-datatypes
.
Subtraction of two dates to yield a duration, and addition of a date to a duration, are not yet implemented.
Casting of a string to a QName, is not supported, except when an explicit cast or constructor function is used in an XSLT environment.
The state of implementation of all the standard functions is described in functions.html
Note that in the dateTime and time data types, the timezone is retained as part of the value. Equality and ordering is done by normalizing the time to UTC, but conversion to a string, and extraction of components, reflects the timezone as originally specified. This is aligned with the current (November 2003) specification.
Support for the type xs:duration
goes beyond what the specification allows.
Ordering is implemented as a total order over all durations, based on the average length of a month
(one year = 365.242199 days).
In replace(), if the pattern matches a zero-length string, each character in the source text is replaced by two instances of the replacement text. This is the Java behavior.
The restrictions noted above with respect to XPath 2.0 apply equally to Saxon's support for XQuery 1.0.
Additional restrictions in Saxon compared with the November 2003 draft of XQuery 1.0 include the following:
The validate
expression is not implemented.
The processor is not schema-aware, and therefore does not support the
import schema
declaration in the prolog.
User-defined functions must have namespace-prefixed names.
The as
clause in variable declarations (both global variables, and for
and let
variables) follow the XSLT rules, which are based on the XPath function calling
rules, rather than the stricter XQuery rules. That is, the supplied value is converted to the declared
type in three ways: atomization of nodes, casting of untyped atomic, and numeric promotion.
The as
clause in some
and every
expressions is not
implemented.
Computed namespace constructors are not implemented.
The rules that determine which namespace nodes should be added to a constructed element are not fully implemented. (The main exception is that in some cases, constructed nodes inherit the namespace of their new parent, which is wrong according to the spec.)
Saxon is dependant on the user-selected XML parser to ensure conformance with the XML 1.0 Recommendation and the XML Namespaces Recommendation.
Saxon implements the <?xml-stylesheet?>
processing instruction as described in the
W3C Recommendation Associating StyleSheets with XML Documents.
The href pseudo-attribute must be a URI identifying an XML document containing a stylesheet,
or a URI with a fragment identifier identifying an embedded stylesheet. The fragment must be the value
of an ID attribute declared as such in the DTD.
Saxon works with any SAX2-conformant XML parser that is configured to enable namespace processing. There is one limitation: on the startElement() call from the XMLReader to the ContentHandler, the QName (that is, the third argument) must be present. According to the SAX2 specification, namespace-aware parsers are not obliged to supply this argument. However, all commonly-used parsers appear to do so.
Saxon should work with any DOM-conformant XML parser, however, Saxon's DOM interface is tested only with Crimson and Xerces, and DOM implementations are known to vary widely.
The XSLT specification says that the documentation for an implementation should specify
which URI schemes
are supported. Saxon supports the URI scheme implemented by the Java java.net.URL
class, with
the optional addition of a fragment identifier, as described below.
Additionally,
Saxon allows the user to nominate a URIResolver class which can be used to implement any URI scheme
the user wants.
The XSLT specification says that the documentation for an implementation should specify for which media types fragment identifiers are supported. The standard URI resolver supports access to XML documents only. A simple fragment identifier is allowed, consisting of the value of an ID attribute in the document. The effect is to return the subdocument rooted at the element with this identifier if there is one, or an empty document otherwise. For example, the URI mydoc.xml#aaa locates the XML document mydoc.xml, and if it contains an element <eeee id="aaa">, where id is an attribute of type ID, then the document retrieved is an XML document with this <eeee> element as its outermost (document) element.
The values of the vendor-specific system properties are:
xsl:version | 2.0 |
xsl:vendor | SAXON n.n.n from Michael Kay |
xsl:vendor-url | http://saxon.sf.net/ |
xsl:product-name | SAXON |
xsl:product-version | n.n.n |
All these values are subject to change in future releases. Users wishing to test whether the processor is Saxon are advised to test whether the xsl:product system property has the value "SAXON".
Saxon implements a number of extensions to standard XSLT, following the rules for extension functions and extension elements where appropriate. The extensions are documented in extensions.html. They are all implemented in accordance with the provisions in the standard for extensibility.
The encodings supported on input depend entirely on your choice of XML parser.
On output, any encoding supported by the Java VM may be used.
There are some differences between the character encodings supported by the old java.io
package
and the new java.nio
package. If the requested encoding is not supported by the java.nio
package, then
all non-ASCII characters will be represented using numeric character references. If the encoding is
not supported by the java.io
package, then Saxon will revert to using UTF-8 as the actual output
encoding. A list of the character encodings
supported in the java.nio
package can be obtained by using the command java net.sf.saxon.charcode.CharacterSetFactory
,
with no parameters.
Collations used for comparing strings can be specified by means of a URI. A collation URI may
be used as an argument to many of the standard functions, and
also as an attribute of xsl:sort
in XSLT, and in the order by
clause of a FLWOR expression in XQuery.
The W3C specifications leave the details of collation URIs entirely implementation-defined. This section explains the collation URIs that can be used with Saxon.
In Saxon XSLT stylesheets, collations may be described using a saxon:collation
element as a top-level declaration in the stylesheet. In this case the value of the name
attribute of the saxon:collation
may be used as a collation URI. There is no constraint
on the form this URI takes, indeed there is no requirement that it be a legal URI.
See saxon:collation for more details.
A collation URI may also be constructed directly. This enables collation URIs to be used in
XPath and XQuery applications as well as in XSLT stylesheets. Such a collation URI takes the form
http://saxon.sf.net/collation?keyword=value;keyword=value;...
. The query parameters
in the URI can be separated either by ampersands or semicolons, but semicolons are usually more
convenient. The keywords available are as follows:
keyword | values | effect |
class | fully-qualified Java class name of a class that
implements java.util.Comparator . |
This parameter should not be combined with any other parameter.
An instance of the requested class is created, and is used to perform
the comparisons. Note that if the collation is to be used
in functions such as contains() and starts-with(), this class must also be a
java.text.RuleBasedCollator . This approach allows a user-defined collation
to be implemented in Java. |
lang | any value allowed for xml:lang, for example en-US for US English |
This is used to find the collation appropriate to a Java locale. The collation
may be further tailored using the parameters strength and
decomposition . |
strength | primary, secondary, tertiary, or identical | Indicates the differences that are considered significant when comparing two strings. A/B is a primary difference; A/a is a secondary difference; a/á is a tertiary difference (though this varies by language). So if strength=primary then A=a is true; with strength=secondary then A=a is false but a=á is true; with strength=tertiary then a=á is false. |
decomposition | none, standard, full | Indicates how the collator handles Unicode composed characters. See the JDK documentation for details. |
It is also possible to specify the Unicode Codepoint Collation defined in the
W3C specifications, currently http://www.w3.org/2003/05/xpath-functions/collation/codepoint
.
In addition, the APIs provided for executing XPath and XQuery expressions allow named collations to be registered by the calling application, as part of the static context.
Saxon can be used with any SAX-conformant XML parser. The extent of XML conformance depends entirely on the chosen parser.
The default parser is the one supplied with JDK 1.4, which is a version of Apache Crimson.
Saxon accepts input (both source document and stylesheet) from any standards-compliant DOM implementation. From version 7.8, when a DOMSource is supplied as the input to a transformation, Saxon works with the DOMSource in situ, rather than copying it to its own internal tree structure. In this scenario, CDATA nodes are treated as text nodes and are not merged with adjacent text nodes. Entity reference nodes are not handled.
Saxon allows the result tree to be attached to any Document or Element node of an existing DOM. Any DOM implementation can be used, provided it is mutable.
Saxon's internal tree structure (which is visible through the Java API, including the case where Java extensions functions are called from XPath expressions) conforms with the minimal requirements of the DOM level 2 core Java language binding. This DOM interface is read-only, so all attempts to call updating methods throw an appropriate DOM exception. No optional features are implemented. The DOM interfaces to Saxon's tree structure do not reveal namespace nodes as attributes. This means it is not possible to get information about namespace declarations except by calls such as getPrefix() and getNamespaceURI() on Element and Attr nodes).
If an extension function returns a DOM Node or NodeList, this must consist only of Nodes in a tree constructed using Saxon. Since Saxon's trees cannot be updated using DOM methods, this means that the nodes returned must either be nodes from the original source tree, or nodes from a tree constructed using Saxon's proprietary API. It is not possible to construct the tree using DOM methods such as createElement() and createAttribute().
Saxon implements the JAXP 1.2 API (originally known as TrAX), which is now documented as a standard part of JDK 1.4. Saxon implements the interfaces in the javax.xml.transform package in full, including support for SAX, DOM, and Stream input, and SAX, DOM, and Stream output.
Note: The transformation interfaces in JAXP 1.2 are identical to JAXP 1.1: the new version only affects the XML parser interface, adding options to control schema validation.
Saxon also implements part of the javax.xml.parsers API. Saxon no longer provides its own SAX parser, however it does provide a DocumentBuilder. The DOM interfaces are limited by the capabilities of the Saxon DOM, specifically the fact that it is read-only. Nevertheless, the DocumentBuilder may be used to construct a Saxon tree, or to obtain an empty Document node which can be supplied in a DOMResult to hold the result of a transformation.
Where the XSLT specification requires that an error be signaled, Saxon produces an error message and terminates stylesheet execution. In the case of errors detected at compile time, it attempts to report as many errors as possible before terminating; in the case of run-time errors, it terminates after the first error.
Where the XSLT specification states that the processor may recover from an error, Saxon takes one of three actions as described in the table below. Either it signals the error and terminates execution, or it recovers silently from the error in the manner permitted by the specification, or it places the action under user control. In the latter case there are three options: report the error and terminate, recover silently, or (the default) recover after writing a warning to the system error output stream. These actions can be modified by supplying a user-defined ErrorListener.
Handling of individual recoverable errors is described in the table below.
This list is incomplete and needs to be reviewed.
Error | Action |
There is more than one template rule that matches a node, with the same import precedence and priority | User option |
There is more that one xsl:namespace-alias statement for a given prefix, with the same import precedence | Recover silently |
An element name defined using xsl:element is invalid | User option |
An attribute name defined using xsl:attribute is invalid | User option |
There are several attribute sets with the same import precedence that define the same named attribute | Recover silently |
A processing-instruction name defined using xsl:processing-instruction is invalid | User option |
A node other than a text node is written to the result tree while instantiating xsl:attribute, xsl:comment, or xsl:processing-instruction | User option |
Invalid characters are written to the content of a comment or processing instruction | User option |
An attribute node or namespace node is written directly to the root of a result tree fragment, or to any other node that is not an element node. | User option |
A value supplied to the value attribute of xsl:number is negative or non-numeric | User option |
The document() function identifies a resource that cannot be retrieved | User option |
There are several xsl:output elements specifying the same attribute with the same import precedence | Recover silently |
disable-output-escaping is used for a text node while instantiating xsl:attribute, xsl:comment, or xsl:processing-instruction | Recover silently |
disable-output-escaping is used for a text node within a result tree fragment that is subsequently converted to a string or number | Recover silently |
disable-output-escaping is used for a text node containing a character that cannot be output using the target encoding | Recover silently |
Michael H. Kay
12 November 2003