SAXON home page

# SAXON: History up to version 5.0

For changes since version 5.0, see changes.html

## Changes in version 5.0 (1999-12-01)

### XSL changes

The following changes are all made to achieve conformance with the XSLT and XPath specifications:

- Top-level elements in the stylesheet that are not recognised as xsl elements or extension elements are now ignored. They can be used to hold lookup data, accessed using document('') which returns a reference to the stylesheet document. SAXON extension elements used at the top level (such as saxon:preview) no longer require "saxon" to be declared as an extension element prefix.

- Global variables in the stylesheet can now contain forwards references to other global variables, and circular definitions are detected.

- xsl:namespace-alias is implemented.

- The [xsl:]exclude-result-prefixes attribute is implemented. Previously, namespace declarations were output only if the namespace was used. Now, as defined in the spec, all namespaces defined on a literal result element are output, unless either they are named in an [xsl:]exclude-result-preifxes attribute on a containing element, or they are declared in an [xsl:]extension-element-prefixes attribute, or the URI is the XSL namespace URI. If a namespace is actually used on a literal result element, the namespace declaration is output regardless.

- The namespace axis and namespace nodes are implemented.

- The unparsed-entity-uri() function is implemented.

- The cdata-section-elements attribute of xsl:output is now namespace-aware

- If the document() function is called several times to load the same URI, the same document node is returned each time. Previously a new document node (and a new tree) was created each time.

- The construct prefix:* is now recognised in xsl:strip-space and xsl:preserve-space.

- If two attribute-sets have the same name, they are effectively merged.

- While evaluating a sort key, the current node list is now the list of nodes being sorted, in document order. So you can now sort in reverse document order by specifing xsl:sort select="position()" data-type="number" order="descending". (This implements an unannounced change in the final XSLT specification, and has required a redesign of the way composite sort keys are handled internally).

- The names of variables, parameters, templates, attribute-sets, keys, modes, decimal-formats, and system-properties are now namespace-sensitive. Names are now checked to ensure they contain valid characters for a QName. Processing instructions are checked to ensure the name is both an NCName and a PITarget.

- All errors that must be reported are now reported. In most cases where XSLT provides the option of reporting an error or recovering, SAXON chooses to recover from it, but this is not invariably true.

Changed the built-in template for attribute nodes (class AttributeCopier) to output only the attribute value, not the entire attribute node.

- When a CDATA section is output, the character sequence "]]>" is now intercepted and split as defined in the standard.

- Implemented the [xsl]:version attribute and forwards compatibility mode.

- The lang attribute of xsl:sort is now recognized. The only language supported directly by SAXON is "en" (English); but additional languages can be supported by writing a user-supplied collating class. The default for the lang attribute is taken from the Java default locale. If no collating class for the language can be loaded, collating is in binary Unicode sequence. This facility can also be used to support user-defined collating sequences for data types such as the names of the months (January, February, etc). For details see extensibility.html. As defined in the final XSLT specification, the data-type can now be a name, and this name is available to the collating class if required; however the selection of a class is still driven by the lang attribute.

- The grouping-size and grouping-separator attributes of xsl:number are now implemented; and non-Latin digits and letters are accepted in the format specification.

- The lang and letter-value attributes of xsl:number are now recognized. The only language supported directly by SAXON is "en" (English); but additional languages can be supported by writing a user-supplied numbering class. The default for the lang attribute is taken from the Java default locale. If no numbering class for the language can be loaded, English numbering is used. The only use made of letter-value in English numbering is that with format="i", the value "alphabetic" can be used to cause a numbering sequence "i", "j, "k" "l", rather than "i", "ii", "iii", "iv". This facility can also be used to support user-defined numbering sequences such as "one", "two", "three", etc. For details see extensibility.html.

- With the "Literal Result Element As Stylesheet" facility, the xsl:version attribute (and therefore the xsl namespace) are now mandatory on the outermost element of the stylesheet. The facility may also now be used on included and imported stylesheets.

- The current() function can no longer be used in patterns.

- The select attribute of xsl:copy-of is now mandatory (previously it defaulted to the current node)

- Code changed to handle multiple key definitions with the same name. If there is one key with name="emp" match="employee" use="@empnr", and another with name="emp" match="contractor" use="@nr", then the function call key('emp','123') will find all employees with empnr=123 and all contractors with nr=123.

- Now allow a NodeTest after '@' in an expression or pattern. For example, @node() is equivalent to @*, while @comment() returns an empty node-set.

- The string-length(), substring() and translate() functions now handle Unicode surrogate pairs correctly, and surrogate pairs are also handled correctly by the XML output method.

- The element-available() function, when the element name is in the XSLT namespace, now returns true only for those XSL elements that are classified as instructions.

- In the format-number() function, the pattern (2nd argument) must now be localized using the characters specified in the relevant decimal-format. For example, if the decimal-separator is "," then the pattern should be written as "####,##" rather than "####.##". There is now a built-in default decimal format equivalent to including with no arguments in the stylesheet (it's not absolutely clear that this is what the XSLT specification intends, but it seems a reasonable interpretation).

- If no xsl:output element is supplied, or if there is no method attribute on an xsl:output element, and if the first thing to be output is a text node, the output method now defaults to "xml" as required by the XSLT specification; previously it defaulted to "text". The output will not be a well-formed XML document, but it will be a well-formed external general parsed entity.

- Comments and processing instructions in the stylesheet are no longer added to the tree. They were previously added to the tree and ignored. The difference is that the text nodes either side of a comment or PI are now concatenated into a single text node, and are only a candidate for whitespace-stripping if both are whitespace-only.

- Any attempt to use an attribute with an unprefixed name on an XSL element, when that attribute is not permitted in the XSLT standard, now results in an error message. As well as conforming to the standard, this feature detects many trivial errors.

#### The following changes affect SAXON extensions:

#### New extension functions

The following extension functions are implemented. The conventional prefix sxf must be mapped to a namespace URI ending in "/com.icl.saxon.functions.Extensions"

- sxf:system-id() returns the system identifier (URI) of the current node in the source document. It take no arguments.

- sxf:line-number() returns the line number of the current node in the source document. It take no arguments.

- sxf:intersection(ns1, ns2) returns a node-set that contains all the nodes that are in both ns1 and ns2. It takes two node-sets as arguments.

- sxf:difference(ns1, ns2) returns a node-set that contains all the nodes that are in ns1 and not in ns2. It takes two node-sets as arguments.

- sxf:has-same-nodes(ns1, ns2) returns a boolean that is true if and only if ns1 and ns2 contain the same set of nodes. (This is different from the "=" operator, which tests whether there is a pair of nodes in the two sets that have the same string-value.) It takes two node-sets as arguments.

- sxf:if(test, p1, p2) returns p1 if test, evaluated as a boolean, is true, and p2 otherwise. Note that p1 and p2 will both be evaluated, one of the values will be discarded. The three arguments may be of any data type.

#### Other extensions

- The extension-element-prefixes and exclude-result-prefixes attributes are allowed on xsl:template as well as on xsl:stylesheet and (with the xsl prefix) on literal result elements. Their scope is the template in question.

- A new saxon:handler top level extension element is introduced, this replaces the previous "handler" attribute on xsl:template. It allows a Java class (a subclass of NodeHandler) to be used to process nodes, in place of an XSLT template. The handler is invoked under the same conditions as an XSLT template, using the same match, mode, name, and priority attributes; it can be invoked either as a result of xsl:apply-templates or xsl:call-template (or even xsl:apply-imports). The capability to invoke both a Java handler and an XSLT template to process the same event is withdrawn.

- The saxon:group extension element is changed so that the "group-by" expression can be any data type; the values are compared directly, rather than being first converted to strings. A group is defined as a sequence of nodes that have the same group-by key when the keys are compared using the XPath "=" operator. The main observable change is that when grouping elements on an attribute value, elements with the attribute absent are no longer grouped together, because "@att=@att" is false when the attribute is absent. To avoid this effect, force conversion to a string by writing group-by="string(@att)".

- A new attribute next-in-chain is introduced on the saxon:output element. This allows the output document produced by the stylesheet to be processed by another stylesheet. The next-in-chain attribute simply gives the URL of the stylesheet that is to perform the next stage of processing. For example "<saxon:output next-in-chain="postprocess.xsl">". This attribute is mutually exclusive with the file attribute of saxon:output.

### Java API changes

- The Propagator has been merged into its parent class, the Controller. References to Propagator can generally be replaced directly with references to the Controller.

- The number of different variants of the applyTemplates() method has been reduced; and the Hashtable used for passing parameters has been replaced by a new class, ParameterSet. Change any affected calls by adding null-valued parameters as required.

- The setDefaultXXXHandler() methods are withdrawn. Use setHandler() with an appropriate pattern instead: for examle, setDefaultElementHandler(h) is replaced by setHandler("*", h).

- The method call setOption(STRIP_SPACE, true) should be replaced by setPreserveSpace(new AnyNameTest(), false)

- An extension function may now declare a first argument of class com.icl.saxon.Context; this argument is not supplied explicitly in the calling XSL, but is supplied by SAXON itself. The Context object gives access to many aspects of SAXON's internal state, for example the current node and context node, and the current outputter.

- The Emitter interface has been changed, so that startElement() and endElement() now take a Name object rather than a String as their first parameter. This allows the Emitter to handle namespace information more easily. The change means that Emitter no longer extends the standard SAX DocumentHandler interface. However, SAXON will still supply the result tree to either an Emitter or a DocumentHandler, as required.

- The interface to the StyleSheet class has been extended, to make it more convenient to supply source data from an application. The application can now call getSourceDocumentHandler() to get a SAX DocumentHandler, to which it can then feed the source document as a sequence of SAX events such as startElement() and endElement(). When the whole document has been supplied, the application should call renderSuppliedDocument() to apply the stylesheet to the document that has been built up. This provides an alternative to registering the preprocessing application as a SAX Parser using setStyleParser(). The setParams() method now requires the global parameters to be supplied as a ParameterSet rather than a Hashtable: note that the name of the parameter must be an interned string, and the value will typically be a StringValue (though any other type of Value will do).

- Java written node handlers no longer have ready access to global variables. (It can be achieved, but requires rather detailed knowledge of the product internals). They can still access local parameters by name, using context.getBindery().getLocalParameter(). These are the parameters supplied by the caller using xsl:with-param.

### Internal changes

There are changes to the package structure.

All the handling of path expressions and nodesets has been changed to use a pipelined approach rather than allocating temporary nodesets in memory. The pipeline only needs to be broken when a sort is required, or when the last() function is executed. This change has little impact on the execution time for typical stylesheets, but should greatly reduce the memory requirement for handling complex stylesheets or large documents, and also eases the load on the garbage collector in a continuous-running environment.

A new sort routine, which is faster and uses less memory, has been introduced.

The Bindery, which holds variable values at run-time, has been changed to identify variables by means of a Binding object (typically the stylesheet node containing the declaration) rather than by name.

### Defects in version 4.7

4.7/001 | The sample servlet ShowScene makes a call on OutputDetails.setXMLDeclaration(); this method was present in version 4.6 but is replaced in 4.7 by setOmitDeclaration(). Fix: delete the offending line (line 58) of ShowScene.java and recompile.
4.7/002 | An attribute node has a null SystemId (URI). This manifests itself when calling the document() function with the first argument being a nodeset containing an attribute node (e.g. "document(@href)"). Circumvention: assign the attribute value to a variable, or convert it to a string using the string() function. Fixed in 4.7.1
4.7/003 | In the document() function, relative URLs in general do not work. Circumvention: supply an absolute URL. Fixed in 4.7.1
4.7/004 | When the node set expression .//x is evaluated, the nodes are not returned in document order, but rather sorted by the document order of the parent node as major key, and the document order of the child node as minor key. This is incorrect, because it is possible for the parent of X to precede the parent of Y in document order even if X follows Y in document order. Fixed in 4.7.1
4.7/005 | When there is no xsl:output element, or no xsl:output element specifies a method attribute, and the first thing output is a text node with no containing element, SAXON defaults to output method="text". The XSLT spec says it should default to XML, and output a well-formed external general parsed entity.
4.7/006 | When xsl:element or xsl:attribute is used and the name includes a namespace prefix and no namespace attribute is specified, the output namespace is incorrect.
4.7/007 | It is possible using xsl:attribute to create several attributes on the same output element that use the same namespace prefix to refer to different namespace URIs. This will generate illegal XML. The fix for this bug replaces the requested prefix with a synthetic one when the situation is detected.
4.7/008 | In the sample extension element sql:connect, the database connection parameters are wrong. This will affect the ability to connect to any database that checks the user name and password.
4.7/009 | In XML output, characters in the range x10000 to x10FFFF (surrogate pairs) are output incorrectly as two surrogate characters: this is not legal XML.
4.7/010 | With the format-number() function, the localized characters for decimal-separator, grouping-separator, etc, are used in the output string but they cannot be used in the pattern. Further, the per-mille attribute name must be written as "permill".
4.7/011 | A null pointer exception occurs if the second argument to the document() function is an empty node-set. (The spec doesn't say what should happen here; the fix treats it as if the second argument were omitted.)
4.7/012 | If a comment or processing instruction is generated before the start of the document element, and if there is no xsl:output method defined, the comment or processing instruction is discarded and does not appear in the result document.
| 4.7/013 | When a stylesheet is prepared once and then used repeatedly to process multiple source documents, a failure occurs if it uses global variables or parameters.

## Changes in version 4.7.1 (1999-10-29)

Fixes bugs 4.7/002, 4.7/003, and 4.7/004

## Changes in version 4.7 (1999-10-12)

### XSL changes

- Renamed the following functions: extension-element-available becomes element-available; extension-function-available becomes function-available; normalize becomes normalize-space.

- Added the terminate="yes"|"no" attribute to xsl:message, and removed the equivalent saxon:abort extension element.

- Renamed the xsl:locale element as xsl:decimal-format, and changed the defaults for the NaN and infinity attributes.

- Renamed the xml-declaration attribute of xsl:output and saxon:output as omit-xml-declaration, and reversed its meaning.

- Changed the XSLT namespace URI to "http://www.w3.org/1999/XSL/Transform"

- The version attribute of the xsl:stylesheet element is mandatory (though forwards-compatible mode is not yet implemented)

- The second argument to the document() function is no longer ignored when the first argument is a node set

- With output method "html", the character '<' in an attribute value is not escaped

- With output method "html", the document type declaration is not output unless either doctype-system or doctype-public (or both) are supplied in xsl:output or saxon:output.

- The full axis syntax child:: and attribute:: is now allowed in patterns

- The use expression in xsl:key need no longer be a nodeset

- xsl:fallback is now available for XSL instructions and SAXON extension elements as well as user-defined extension elements

## Changes in version 4.6 (1999-10-08)

This version was not released, as it was completed just as the 8 October 1999 specification was released.

### XSL changes

- Added support for Namespaces. Including the use of namespaces in the source document and stylesheet; the generation of namespace declarations in the output document; the use of namespace prefixes in names occurring within XSLT expressions and patterns; and the use of the wildcard construct "prefix:*" in expressions and patterns; the namespace() function; the namespace attribute of xsl:element and xsl:attribute; the namespace prefix on extension functions; the prefix in extension-element-prefixes. But not yet the namespace axis.

- If SAXON extensions are used, the namespace URI for the "saxon" namespace must be "http://icl.com/saxon"

- Changed the interface for extension functions. The new mechanism is modelled on that in James Clark's xt. An extension function must have a non-null namespace; the class containing the function is identified by everything after the last "/" in the namespace URI. The method implementing the function is the first method in that class that matches the local name of the function, ignoring hyphens and case, and that has the right number of arguments. The arguments of the method, and its return type must be of appropriate types: one of boolean, double, String, com.icl.saxon.expr.NodeSetValue, or com.icl.saxon.expr.FragmentValue. There is no way currently for the extension function to obtain information about the context (e.g. the current node). The saxon:functions element is now superfluous and is withdrawn.

- Implemented element extensibility, and reinstated SQL Stylesheets (which allow data from the source XML document to be inserted into a relational database) as an example of their use.

- Implemented xsl:import and xsl:apply-imports

- Implemented handling of "}" and "}}" within attribute value templates as specified in the XSLT recommendation (as well as correcting error 4.5/001 below).

- Comment nodes are now fully supported. Note however that comment nodes are only available to SAXON if a (non-standard) SAX driver is used that notifies comments as if they were processing instructions with a null target name. The only driver I know of that does this is com.jclark.xml.sax.CommentDriver, which can be selected in the ParserManager.properties file. If any other SAX driver is used, comment nodes will be silently ignored.

- Implemented the current() function

- Implemented the data-type and case-order attributes of xsl:sort. (But note that the default order is still binary collating sequence, rather than being locale-sensitive).

- A number may now begin or end with a decimal point

- xsl:variable, xsl:param, xsl:with-param, and saxon:assign now evaluate to a zero-length string (rather than an empty result tree fragment) if there is no select attribute and no content.

- The default-space attribute of xsl:stylesheet is removed. In its place, use xsl:strip-space or xsl:preserve-space with elements="*". The "prefix:*" syntax is not yet supported.

- Added disable-output-escaping attribute to xsl:text and xsl:value-of

- Added support for a relational comparison between a node-set and a result-tree-fragment. (The result-tree-fragment is treated as a string)

- Added xsl:output element; replaced "result-ns" and "indent-result" attributes on xsl:stylesheet with new "method" and "indent" attributes on xsl:output. Most of the attributes of xsl:output are implemented, and the details of HTML outputting in particular are greatly enhanced.

- Output can now be directed to a user-defined class. This can be either a standard SAX DocumentHandler, or an implementation of the com.icl.saxon.output.Emitter interface, which is an extension of the DocumentHandler interface. If an Emitter is used, more information is available to the user-defined class, for example the various options on the xsl:output element; also comments are passed through which is not possible with a standard DocumentHandler. Simply give the fully-qualified name of the Emitter or DocumentHandler class as the value of the method attribute on xsl:output or saxon:output.

- The attributes on the new xsl:output element are also made available on the saxon:output element. The "format" attribute of saxon:output is renamed "method"; its values are "xml", "html", "text", "fop", or the name of a class that implements com.icl.saxon.output.Emitter

- The saxon:tag element is withdrawn. Use xsl:text with disable-output-escaping="yes" instead.

- The capability on saxon:output to write to an attribute of an ancestor element has been replaced by a more general saxon:set-attribute extension element. This takes a mandatory "name" attribute, defining the name of the attribute to be set; and an optional "select" attribute whose value is a string expression. The new value of the attribute is defined in the same way as for xsl:variable, either by the "select" attribute or by the contents of the saxon:set-attribute element. To convert existing stylesheets that write to an attribute of an ancestor element named A, use saxon:set-attribute within a <xsl:for-each select="ancestor::A">

- References to global variables are no longer allowed within the match pattern of xsl:template or xsl:key, nor within the use expression of xsl:key. Instead, it is now possible for the definition of a global variable to use xsl:call-template, xsl:apply-templates, or the key() function.

- The internal implementation of Result Tree Fragments has changed. The only observable effect of this is that a result tree fragment must be well-formed XML: it is not possible to disable output escaping, or to use saxon:entity-ref within a result tree fragment.

- An extension function is provided to convert a result tree fragment to a nodeset. Calling sxf:nodeset($fragment) returns a node set containing a single document node; the outermost element has the name RESULT-TREE-FRAGMENT, and this in turn contains the actual nodes added to the result tree fragment. This document can be processed in the same way as a secondary document loaded using the document() function. This capability allows a stylesheet to create working data of arbitrary complexity which it can then use later in the processing. (The prefix sxf should map to a namespace whose URI ends with "/com.icl.saxon.functions.Extensions")

- Implemented Literal Result Element As Stylesheet (section 2.3 of the XSLT specification).

- Implemented an interface to James Tauber's FOP (Formatting Object Processor). FOP allows you to generate PDF output instead of HTML, using the fo: set of literal result elements. FOP must be downloaded and installed separately. It can be invoked simply by executing the SAXON stylesheet with method="fop" specified on xsl:output or saxon:output. SAXON is tested with FOP version 0_10_0.

- Removed the SAXON proprietary syntax for accessing an inherited attribute.

- Added preview mode. This replaces the facility in earlier SAXON releases for serial processing. Preview mode allows a template to be called while the document is being built in memory, as soon as the end tag of a specified element is encountered. The preview template sees a tree that appears structurally complete, but contains only those nodes that (a) precede the current node in document order or (b) are its descendants. Once the template has been executed, the children of the specified node (but not the node itself) are discarded to release memory. The XSL elements to define a preview element is saxon:preview

- Improved diagnostic tracing facilities. The attribute saxon:trace="yes" or "no" may now be applied either at the xsl:template level or at the xsl:stylesheet level (it is treated as an inherited attribute). If the value for a template is "yes", every activation of that template results in a line of output to System.err, identifying the stylesheet template and the current node in the source document, by element type and line number. Tracing only occurs if the template is activated by matching the pattern, not if the template is called by name.

### Java API changes

There are numerous changes to support the new XSL facilities. These are not listed individually.

- Some classes have moved to a different package, e.g. Outputter is now in com.icl.saxon.output. This will affect import statements.

- setOutput() is replaced by setOutputDetails(), which allows you to specify many more details of the output format required, e.g. indenting, encoding, DOCTYPE details, and so on. Note that when setOutputDetails() is called to switch to a new output file, a new Outputter is allocated, so getOutputter() must be called to obtain access to it.

- In the Context class, getCurrentNode() is renamed getContextNode(), and a new method getCurrent() is introduced. getContextNode() returns the context node, while getCurrent() returns the current node. They will only be different when evaluating a sub-expression, so the difference will only be visible to applications when implementing an extension function called from a subexpression.

- The API to the com.icl.saxon.StyleSheet class has changed. You can now specify different parsers for the source document and the stylesheet (useful, for example, if you want one validated and the other not, or if you want to filter the source document before it is processed by the stylesheet). You can specify full details of the output destination using setOutputDetails(), which replaces the previous setOutput(). The two main calls are prepareStyleSheet(), which does all the parsing and preprocessing of a stylesheet, and renderSource(), which applies the stylesheet to a particular source document. A stylesheet, once prepared, can be used repeatedly to render different source documents.

- The element handlers ElementRedirector, ElementSorter, NumberHandler, and AttributeWriter are withdrawn. These functions can be carried out much more easily using XSL, or by using XPath expressions within your Java program. For example, the sample program ShowBooks.java shows how to use a SortedSelection expression to do sorting.

- The various setDefaultXXXHandler() methods are merged: instead of setDefaultElementHandler(x), use setDefaultNodeHandler(NodeInfo.ELEMENT, x).

- There are many details changes to the tree navigation interfaces caused by the introduction of namespaces. In many cases methods that took an element name as parameter now take a Pattern instead: to search for a named element, create a NamedNodePattern.

- The default attribute name used in the NumberHandler element handler has changed from "saxon:nr" to "saxon.nr", to allow its use when the "saxon" namespace has not been declared.

### Miscellaneous changes

- Added line number and URL to all nodes, and now use this in reporting stylesheet errors

- Updated the list of HTML elements that are output without an end tag to include all elements listed in section 15.2 of the 13 Aug 1999 XSLT specification

- Added optimisation for the predicate "[1]" in filter expressions and steps: this means, for example, that "following::X[1]" will no longer find all the following nodes in the document and then test each one to see if it is the first.

- Changed the command line interface to com.icl.saxon.StyleSheet: you can now specify an output file using the -o argument.

### Defects in version 4.5

The following bugs are fixed in version 4.6, except where stated:

4.5/001 | In attribute value templates, the use of '{{' to represent an escaped '{' does not work. SAXON reports a syntax error. (Note that the use of '}}' to represent an escaped '}' was not supported in version 4.5 either, but this was by design.)
4.5/002 | If the ParserManager.properties file cannot be found, SAXON reports an unspecific null pointer exception.
4.5/003 | The built-in template for attribute nodes ignores the attribute rather than copying it to the output tree.
4.5/004 | The standard element handler ElementCopier writes a newline to the output file after writing the element end tag.
4.5/005 | SAXON 4.5 is not thread-safe. (I have made changes that fix known problems in this area, but I cannot guarantee that everything concerned with threads is now OK.)
4.5/006 | The sample file play.xsl, mentioned in the documentation, was missing from the distribution. ** changes not yet applied **
4.5/007 | The document() function does not work when used in a select expression in a global variable or parameter declaration
4.5/008 | The "ns" (namespace) attribute of saxon:functions has no effect: extension functions must be referenced without a namespace prefix
4.5/009 | If a step in a path expression contains more than one filter, and one of the filters removes all elements of the nodeset, and a subsequent filter is numeric, then an ArrayIndexOutOfBoudsException occurs at com.icl.saxon.expr.Step.applyFilters(Step.java:140)
4.5/010 | SAXON gives the wrong result when comparing a nodeset NS with a boolean B. The semantics assumed by SAXON are "exists X in NS where boolean(X) = B", whereas the correct semantics are "(exists X in NS) = B"
4.5/011 | If there are several templates with the same name, xsl:call-templates chooses the first on rather than the last. The same applies to named attribute sets.
4.5/012 | The use of xml:space="preserve" on a node prevents white space being stripped not only from the descendants of that node, but also from subsequent siblings of that node and their descendants.
4.5/013 | The issued sample file books.xml is not valid. It contains an IDREF attribute (CODE="U") for which there is no corresponding ID attribute. A validating parser will therefore reject this document. Also, the sample stylesheet books.xsl attempts to process this attribute using the "default" attribute of xsl:value-of, which is no longer supported in SAXON 4.5

## Changes in version 4.5 (1999-07-28)

Please note that many of these changes require changes to stylesheets or applications. Sorry! This is all in the interests of improved conformance with the standards.

### XSL changes

- Added string-length() and substring() functions
- Renamed expr attribute as select on xsl:param, xsl:param-variable, and xsl:variable
- Renamed xsl:param as xsl:with-param, and xsl:param-variable as xsl:param
- Changed syntax for axes from "from-xxx(node)" to "xxx::node". The axis names are also changed, typically from plural to singular nouns.
- Renamed qname() as name()
- Renamed pi() as processing-instruction()
- Renamed multi (on the level attribute of xsl:number) as multiple
- Renamed expr attribute on xsl:number as value
- Renamed per-mill attribute on xsl:locale as per-mille (and corrected the names of the other attributes)
- Implemented system properties xsl:vendor and xsl:vendor-url
- The first argument of boolean() is now mandatory
- Changed behaviour of translate() when the 2nd and 3rd arguments are different lengths
- Renamed function-available() as extension-function-available()
- Combined key() and keyref() into new key() function
- Combined id() and idref() into new id() function
- Changed following axis to skip the descendants of the start node
- Changed preceding axis to skip the ancestors of the start node
- The default priority on templates is now dependant on the pattern
- Added support for processing-instruction nodes
- Renamed xsl:pi as xsl:processing-instruction
- Replaced xsl:use element by use-attribute-sets and xsl:use-attribute-sets attributes
- Changed built-in templates (default handlers) for document and element nodes to continue processing in the same mode
- Implemented xsl:include (in the Interpreter and Compiler)
- Allowed xsl:transform as a synonym of xsl:stylesheet
- Removed the xsl:id element. The id() function now works on any ID reported by the XML parser. Note that IDs will not be reported unless there is a DTD, and unless a parser is used that reports them to the application. Parsers known to do this include SUN, IBM xml4j, and AElfred. James Clark's xp parser appears not to do so.
- Implemented the document() function. Current restrictions: target must be XML; no support for fragment identifier in URL; supported in interpreter only.
- Implemented the != operator and changed rules for comparisons where one or both operands is a node set.
- The select attribute of xsl:for-each is now mandatory (previously defaulted to "node()")
- Changed the SAXON extension elements assign, entity-ref, item, output, tag, and while to have a saxon: prefix rather than an xsl: prefix, in line with the XSL extension elements specification. xsl:for-each can no longer have a group-by attribute; this functionality is provided by a new saxon:group element. The xsl:functions element is renamed saxon:functions, and its "type" attribute is now ignored. These elements are only available if the extension-element-prefixes attribute on the xsl:stylesheet node, or the xsl:extension-element-prefixes attribute on an enclosing literal result element, is set to "saxon".
- Extended xsl:copy-of to work on values other than node sets; changed the effect of xsl:value-of when applied to a Result Tree Fragment value so it no longer outputs the tags. Note that xsl:copy-of is more efficient than xsl:value-of to copy simple result fragments to the output file.
- Changed the effect of indent-result="yes" so it only affects the primary output file. It no longer affects output destinations created using saxon:output or result fragments assigned to a variable. (This is because xsl:copy-of was repeating the indentation process)
- Minor changes to xsl:number, in line with the spec. This affects the numbering of nodes other than elements, and the effect of level="any" when the current node doesn't match the count pattern
- Removed the abort attribute of xsl:message; added a new element saxon:abort which unconditionally prints a message (the contents of the element) and abandons processing

### Java API changes

There has been some radical surgery of parts of the code not needed for XSL: I have removed Distributor, Wanderer, support for the DOM, and the associated node implementations. Also removed Renderer, and setItemRendition() etc from Controller.

This is all in the interests of reducing complexity: this code does things that can now be done more easily using XSL.

I hope to reintroduce serial processing in a later version, in amended form.

- renamed isRootElement() and getRootElement() as isDocumentElement() and getDocumentElement()
- Removed facility for storing user data in a context (use variables instead)
- Removed getParent() and hasParent() interfaces from NodeInfo: use getParentNode() instead
- Removed the versions of getFirstChild(), getLastChild(), getNextSibling(), getLastSibling() that take a node-type parameter: use a NodeTestPattern (or simply an inline loop) instead.
- Removed the redundant methods getFirstInGroup(), getLastInGroup()
- Removed getTag(): use getName() instead
- Controller/Propagator interfaces rationalised to remove the "single-document" assumption (except that you can only be parsing one document at any one time).
- Logic (and interfaces) for manipulating IDs and Keys has moved from Controller to DocumentImpl, so that there can be a separate index for each source document. Indexing is now done lazily, the first time the id() or key() function is used in a particular document.

### Defects in version 4.4

The following bugs are fixed in version 4.5, except where stated:

4.4/001 | generate-id() fails (null pointer exception) when applied to the document root.
4.4/002 | Filter expressions using predicates at the outer level (not as part of a step) fail, with the error "Unexpected token "[" in expression". (Example: "$test[1]")
4.4/003 | When using the XSL compiler, when a number is used in a boolean context (e.g. <xsl:if test="2">), the boolean condition is evaluated the wrong way round: zero is taken as true, and non-zero as false.
4.4/004 | A class cast exception occurs when the argument to the count() function is not a node set.
4.4/005 | After an xsl:pi element, all subsequent text is output without escaping special characters such as "&" and "<".
4.4/006 | Conversion of a result tree fragment to a string does not discard the markup as it should. Conversion of result tree fragments to numbers or booleans is also incorrect.
4.4/007 | The class org/ccil/cowan/sax/ParserFilter.class was omitted from saxon.jar (It can be downloaded separately John Cowan's web site, or created by compiling the source which is included in src.zip). (This class is not needed with SAXON 4.5)
4.4/008 | The xml:space attribute on a stylesheet node has no effect.

## Changes in version 4.4 (1999-07-12)

This is a performance release: there are very few changes in functionality. The majority of changes are purely internal. Detailed changes to methods provided primarily for internal use are not listed here.

Applications should be recompiled.

### Changes to XSL stylesheets

- The rules on the scope of variable names are now more strictly enforced, in both the compiler and the interpreter. It is no longer possible to access parameters that were supplied (using xsl:param) but not declared (using xsl:param-variable).
- The default attribute on xsl:value-of (an undocumented SAXON proprietary feature) is no longer supported. The select attribute on xsl:value-of is now mandatory.
- Serial stylesheets are not supported in this release. They may be re-introduced at a later release. They have been withdrawn because the mechanism previously used gave no performance benefits.
- A packaged version of the interpreter is provided as a Windows-32 executable. This incorporates a copy of the AElfred XML parser as standard, and requires no external software to be installed other than the Microsoft Java VM (which will already be installed if you use Internet Explorer).

### Changes to the Java API

- In general, names of elements and attributes passed across the API must now be interned Strings. (If the name is passed as a literal, it will be interned anyway; if not, use "name=name.intern()")
- Changes may be needed to code implementing extension functions. These must be defined as subclasses of com.icl.saxon.expr.Function.
- The API no longer gives access to named templates by name at run-time.
- The Propagator is introduced as an alternative to the Distributor and Wanderer. Like the Wanderer, the Propagator builds a tree and then processes its nodes by calling the registered element handlers. However, it builds its own tree rather than wrapping a standard DOM. This gives a performance benefit (because implementation details of the DOM can be exploited, and because the wrapper classes are no longer needed), and it allows nodes in the tree to be subclassed - something which many DOM implementations allow, but not within the standardised DOM interface.
- It is no longer possible to define handlers for user-defined elements in the stylesheet. A replacement mechanism, conforming to the 9 July 1999 XSLT specification, will be introduced in a later release. This means that "SQL stylesheets" are also withdrawn for the time being.
- The method expandAttributeValueTemplate() in the Context class is no longer available; instead it is necessary to create an object of class AttributeValueTemplate, and evaluate it using its evaluate() method.

### Miscellaneous changes

- The ORACLE DOMBuilder has been updated to work with the ORACLE v2 parser. The v1 parser is no longer supported.
- There is a new packaging of the SAXON XSL interpreter for the Windows platform, referred to as "Instant SAXON".
- The BinaryTree class used by SAXON for sorting has been changed to return its results as a Vector rather than an Enumeration.

### Defects in version 4.3

The following bugs are fixed in version 4.4:

4.3/001 | The XSL interpreter ignores xsl:strip-space and xsl:preserve-space elements
4.3/002 | In xsl:attribute the name attribute cannot be an attribute value template

### Future changes expected

There is no commitment to produce any future release of SAXON. However, the following changes are under consideration:

- Conformance to the 9 July 1999 (or later) version of the XSLT specification. Note this will involve some incompatible changes.
- Dropping the handler="" parameter on xsl:template. This is no longer needed, given the extension mechanisms defined in the XSL standard.
- Dropping the Wanderer and support for the DOM. This is not needed to support XSL, and it gives no extra functionality compared with the Propagator, while adding to the product size and complexity.
- Incorporation of SAXON XSL extensions within the extensibility framework defined in the standard. In most cases this will simply involve renaming elements, for example xsl:output will become saxon:output.
- General trimming-back of functionality in the Java API that is not needed for XSL support.

## Changes in version 4.3 (1999-06-14)

### Changes to expression and pattern syntax

#### Incompatible changes

A number of incompatible changes have been introduced to reflect the latest XSL working draft. These include:

- constant() is no longer supported: use variables instead
- counter() is no longer supported: use variables instead
- the name() function is renamed qname()
- ancestor() and ancestor-or-self() are replaced by from-ancestor() and from-ancestor-or-self(). The argument is now a simple name rather than a match-pattern, and it retrieves all matching ancestors not just the first.
- first-of-any(), first-of-type(), first-of-group(), last-of-any(), last-of-type(), and last-of-group() are no longer supported.
- The xml() function is withdrawn

#### New features in expressions and patterns

See the April 21 XSLT specification for full details. Changes include:

- The document node can now be matched using "/"
- Multiple predicates/filters in a path expression
- Positional predicates/filters using integer values, position(), and last()
- Variables can be referenced in expressions: e.g. $name
- Expanded syntax for expressions using named axes, as in the XSLT WD
- Numerous operators and functions for manipulating numeric, boolean, and string values, as in the XSLT WD

### Changes to XSL stylesheets

#### Incompatible changes to XSL stylesheets

- Constants and counters are no longer supported: use variables instead
- The 'test' attribute of xsl:when and xsl:if is now a boolean expression, not a match pattern.
- The old xsl:param element (used only to declare parameters for Java-written element handlers) is subsumed into the new xsl:param-variable. The actual parameters are now supplied in the call, though it is still possible to supply constant parameters as defaults.
- SAXON's proprietary extension to xsl:if (using xsl:then and xsl:else) is dropped. Use xsl:choose, xsl:when, and xsl:otherwise.
- The proprietary saxon:trim attribute is withdrawn. Whitespace stripping now conforms with the XSLT recommendation. TIP: when generating HTML, if you want to avoid having to put in lots of xsl:text elements to preserve spaces and newlines, set xml:space="preserve" on the xsl:stylesheet element.
- The proprietary saxon:escape attribute is withdrawn. In its place is a new attribute saxon:format (on xsl:stylesheet) or format (on xsl:output) that takes the values "XML", "HTML", or "TEXT". This defines the format of the output file, which in turn controls whether special characters are escaped. One impact of this is that it is no longer possible to construct tags, processing instructions, or other paraphernalia in an XML file as if it were text. (The xsl:tag element, however, remains available).

#### Newly-implemented XSL features

See the XSLT specification for further details. Changes include:

- Named templates and xsl:call-template
- Variables and parameters to templates
- xsl:message (with an additional non-standard attribute "abort": set this to "Y" to abort processing). The message output is directed to System.err
- xsl:attribute-set and xsl:use (with a restriction that multiple attribute sets with the same name are not merged)
- User-defined extension functions
- Keys
- Locales
- xsl:preserve-space, xsl:strip-space, default-space attribute on xsl:stylesheet (value "strip"), support for xml:space attribute (values "preserve" and "default").
- xsl:entity-ref has been added. "<xsl:entity-ref name="eacute"/>" generates the output "&eacute;". This is a non-standard extension.
- xsl:assign and xsl:while (proprietary SAXON extensions)

### Changes to the Java API

#### Incompatible changes in the Java API

A number of incompatible changes have been made in the interests of XSL conformance.

- All node handlers (element handlers, etc) take a second parameter, the Context. Services such as write() and applyTemplates() that were previously available via the first (NodeInfo or ElementInfo) parameter are now available via the Context parameter. (In the case of outputting functions, call context.getOutputter() to obtain the current Outputter, then use methods such as outputter.writeContent().)
- Handlers can now receive and pass parameters, and declare variables for use in expressions.
- Some navigational methods have been renamed for clarity, reflecting the fact that you can now navigate around all the nodes of the Document, not just the element nodes. For example, getRoot() which used to find the outermost element is renamed getRootElement(): to find the DocumentInfo element, use getDocumentRoot(). Other methods such as getNextSibling() now take a node-type parameter: to find the next element node, use getNextSibling(NodeInfo.ELEMENT).
- In line with changes in XSL, the classes representing patterns and expressions have been reorganised. MatchPattern is renamed Pattern; SelectPattern is replaced by NodeSetExpression (a subclass of Expression); StringExpression has been replaced by the more general Expression. The com.icl.saxon.pattern package has been renamed com.icl.saxon.expr.
- The methods for numbering nodes have been rationalised.
- The methods that supported the obsolete XSL features of constants and counters have been withdrawn.
- The DOM Document node is no longer exposed in the Wanderer interface; like all other nodes, this is now wrapped by a SAXON-specific DocumentInfo node.

#### New features in the Java API

These are largely methods that support the new XSL features.

- Methods to register and call handlers by name (rather than by pattern matching) are introduced.
- Methods are introduced to register which elements are to preserve whitespace, and to strip whitespace nodes from the tree.
- The new Context and Bindery objects provide additional functionality.

### Miscellaneous changes (environment, internal code changes)

- Upgraded ParserFilter to use John Cowan's latest version.

## Defects in version 4.2

The following bugs are fixed in version 4.3:

4.2/001 | XSL Compiler generates "include" statements for servlet API even when servlet="N" is specified. This causes the compilation to fail under JDK 1.1.

## Changes in version 4.2 (1999-04-23)

### Changes to XSL stylesheets

#### Incompatible changes to XSL stylesheets

- Changed command-line interface to StyleSheet: constants can now be supplied in the form name=value rather than -Xvalue.
- The xsl:option element has been replaced by attributes on the xsl:stylesheet element.
- You can no longer have several templates that match the same element; and the system no longer attempts to determine which template is the most selective. You must now use explicit modes and priorities as specified in the XSL standard.

#### New XSL features

- Added an XSL Compiler. This allows an XSL stylesheet to be compiled to generate a Java SAXON application. The application (which may be run as a servlet) performs the same rendering as the original stylesheet.
- Added mode and priority to xsl:template and xsl:apply-templates
- Added xsl:call element, to call useful string-handling functions.
- Added a default attribute to xsl:value-of.
- Added the ability to match attributes (@name and @*) in match-patterns and select-patterns.
- Added support for match-patterns of the form "*/text()" to match a character-data node in the source document: allows a template to be defined for rendering character data. (Note: the select-pattern */text() is not yet supported)
- Added a new group-by attribute to xsl:for-each. The value is a string expression. The xsl:for-each element should contain a nested xsl:item element: the xsl instructions within the xsl:for-each but outside the xsl:item are executed only for the first/last item in a group of consecutive items with the same value for the group-by expression.
- Added support for xsl:sort in xsl:for-each and xsl:apply-templates. Allows multiple sort keys, ascending or descending, but with no control over collating sequence. In xsl:apply-templates, sorting is only allowed when there is an explicit select-pattern. The new class SortedSelection is also available for use in Java applications.
- Implemented xsl:number: level= single or any, with count attribute, simple format attribute. There is a corresponding string expression number(match-pattern). Underlying this is are new methods available to Java applications, NodeInfo.getNodeNumber() and NodeInfo.getNodeNumberAny().
- Added xsl:counter, xsl:counter-reset, and xsl:counter-increment. These support a single set of named counters attached effectively to the root element. This provides all the facilities of XSL counters except the ability to handle recursive structures, e.g. nested DIV elements. Also added a new StringExpression counter(name), so that counters can be accessed within attribute value templates and tested within qualifiers.
- Added support for xsl:id at the start of a select pattern (single ID only, not a space-separated list as in the XSL specification). (Current deficiency, works only if the root element is processed by an explicit XSL template)

### Changes to the Java API

#### Incompatible changes in the Java API

A number of incompatible changes have been made in the interests of XSL conformance.

- The old ElementHandler interface has been split into two: ElementHandler and CharacterHandler. Separate handlers must now be registered for handling elements (start, end, start of group, end of group) and character data. This has a significant effect on existing applications, but the change had become necessary. Firstly, modes don't work properly if the same handler is used for both purposes. Secondly, it's necessary to move towards the XSL processing model where templates can be defined both for elements and for other nodes such as character data, attributes, comments, etc. If you want to make minimum change to applications, declare your handler to implement both interfaces and register it for both purposes. (In my experience, however, most handlers use one of the default behaviours for character data).
- The old setDefaultHandler() method is replaced by two new methods: setDefaultElementHandler() and setDefaultCharacterHandler().
- The standard element handlers are now in package com.icl.saxon.handlers: you may need to add import statements to pick them up.
- beforeGroup() and afterGroup() are no longer intrinsic methods of every element handler; rather they are available only in subclasses of GroupHandlerBase. To achieve this, the Distributor now uses a ParserFilter with lookahead: when an end tag is encountered, it looks ahead to see what the next start or end tag is. This means that the isLastInGroup() and isLastChild() methods are now available (during end-element processing only) with the Distribtor as well as the Wanderer.
- The class ElementHandler is now a subclass of the more general class NodeHandler which handles all kinds of nodes. This provides two methods only: start() and end(). In subclasses of ElementHandlerBase, however, the traditional startElement() and endElement() are available. These take care of the casting of the NodeInfo argument to an ElementInfo.
- It is no longer possible to set multiple handlers for the same pattern by simply making several calls on setHandler() (or by specifying several templates in a stylesheet). This change is made in the interests of XSL conformance, and to avoid the problems that arise with the increasing complexity of patterns. You can still set multiple handlers in a Java application by explicitly instantiating a MultiHandler (see com.icl.saxon.handlers.MultiHandler). In a stylesheet, you can specify both a Java handler and an XSL template by including both in the same xsl:template element. (The Java handler is always invoked first: this is useful for filtering the input. Typically the Java handler will set attributes that the XSL can read.) A side-effect of this change is that the "packaged" interface Controller.setNumbering() is no longer any use, so it has been withdrawn. You can often achieve the same effect using counters; if you still want to use the NumberHandler, you can invoke it directly.
- The standard handler ElementToAttributeConverter is now a character data handler rather than an element handler. This means the match pattern to invoke it must be changed from "TITLE", say, to "TITLE/text()".

#### New features in the Java API

These are largely methods that support the new XSL features.

- Added ability to use attributes (@name and @*) in match-patterns and select-patterns. Added class AttributeHandler as a subclass of NodeHandler.
- Added support for match-patterns of the form "*/text()" to match a character-data node in the source document: allows a template to be defined for rendering character data. (Note: the select-pattern */text() is not yet supported)
- Underlying the xsl:number element in style sheets there are new methods available to Java applications, NodeInfo.getNodeNumber() and NodeInfo.getNodeNumberAny().
- Added mode and priority to the setHandler() and applyTemplates() methods, corresponding to the equivalent XSL facilities.

### Miscellaneous changes (environment, internal code changes)

- Added a driver for Datachannel DOM implementation. (However, I encountered several problems with this product which are not resolved at time of writing.)
- Separated SelectPattern and MatchPattern as two separate classes; and SelectPattern is now a subclass of StringExpression. User-written element handlers may need to change to use the new classes in place of the general-purpose Pattern class, which is withdrawn.
- Split the code into multiple packages.

## Defects in version 4.1

The following bugs are fixed in version 4.2:

4.1/001 | After executing xsl:for-each, the current source element is not reset, so a subsequent xsl:for-each (for example) will process the wrong element.
4.1/002 | Where a qualifier is used of the form "[s1=s2]", a null pointer exception occurs if the second value is null.
4.1/003 | If a template in a serial style sheet does not contain xsl:apply-templates, processing hangs indefinitely.
4.1/004 | For an element that is the same element type as its previous sibling, the Distributor assumes that it can use the same element handler. This is not true if the match pattern depends on attribute values.
4.1/005 | The DTDGenerator sample application fails (array index out of bounds) if it encounters a zero-length attribute

## Changes in version 4.1 (1999-03-12)

- A brand new Pattern parser that supports most of the XSL syntax for match patterns and select patterns, with associated classes so that these can be used from Java applications as well as XSL Stylesheets. Note that 4.01 pattern syntax may need updating where it didn't conform to XSL rules.
- A lot of extra XSL elements, including xsl:copy, xsl:element, xsl:attribute, xsl:choose, etc, etc. Including corrections to one or two that were incorrectly implemented.
- Serial style sheets, allowing large XML documents to be processed sequentially using a subset of the XSL syntax
- SQL style sheets: a demonstration of how SAXON XSL can be extended, in this case to allow data to be loaded into a relational database
- An enhanced DTDGenerator to detect elements containing the same children every time in the same sequence
- Added ElementInfo.getExtendedContent() and ElementInfo.getXML()
- getHandler() accepts a general match pattern. Because if uses the new pattern parser, it can now throw an exception if the pattern is incorrect.

### Limitations of this release

I have given up trying to test each new SAXON release with every possible SAX parser and DOM implementation: there are too many, with many new releases, and on the whole the level of conformance is good. Most of the time I use either the SUN XML library, or the xp parser and Docuverse DOM. I have had problems with the latest IBM xml4j version 2, (2_0_0 and 2_0_3), I understand this is due to a parser bug and a fix is available but I haven't tried to install it. I haven't been able to download the latest ORACLE parser because of broken links on ORACLE's web site, plus excessive registration hassle.

This does mean that the IBMDOMDriver and ORACLEDOMDriver classes (now located in the com.icl.saxon.drivers package) are untested against the latest IBM and ORACLE DOM implementations.

Please let me know what parsers you are using successfully with SAXON, especially if you have to make any changes to the ParserManager.properties file or to the DOM drivers.

## Changes in version 4.01 (1999-02-18)

This is an error-correction release

- ParserManager, if it succeeds, no longer outputs the name of the parser it has loaded
- The command line for com.icl.saxon.StyleSheet now allows the list of constants to be empty
- Distributor.getCurrentElement() now works correctly during endElement processing
- There were a number of problems associated with use of the default output destination, System.out. In some circumstances output sent to this destination disappeared silently. In some circumstances multiple outputs were being sent to System.out, and sometimes System.out was being closed prematurely. The only satisfactory solution I have been able to find is to abandon the idea of a default output destination entirely. It is therefore necessary for the application to explicitly supply an output writer (using either ElementInfo.setWriter() or Controller.setWriter()) before any output is performed, and to close it on completion (e.g. by use of the corresponding resetWriter() method). The sample applications have been changed accordingly.

Please note the following restrictions:

- A number of patterns do not conform correctly to the XSL syntax or semantics. Notably ancestor(X)@attribute is missing a "/", and in <xsl:apply-templates>, the patterns to search children and descendents respectively should be "XXX" and ".//XXX" rather than "./XXX" and "XXX". This will be fixed in a subsequent release.
- SAXON does not work with the current (18 Feb 1999) version of the xml4j_2_0_0 parser. This is a bug in xml4j and IBM have a fix available.
- There is no <xsl:copy> command available. To copy elements from the source document to the output document, use:

  `<xsl:template match="*" handler="com.icl.saxon.ElementCopier"/>`

## Changes in version 4.0 (1999-02-12)

- To ensure that element handlers are consistent when processing serially (using SAX) or directly (using the DOM), an incompatible change has been made: if you want child elements to be processed (the normal case), you must call applyTemplates() as the last thing your startElement() method does. If you don't do this, element handlers will not be called for child elements or character data within this element. (The setDisableChildren() interface, which was previously used to suppress processing of children, is now withdrawn.)
- The role of the Renderer class is much diminished: it now purely acts as a main program front-end for Distributor and Wanderer. Most of the functions previously in Renderer have been moved up into the Controller class, to make them equally accessible when doing direct or serial processing, and Renderer is no longer a subclass of Distributor.
- The handling of multiple output writers has changed. The ability to associate a writer statically with an element type (by pattern) has been withdrawn, because of problems knowing when to close a writer. A new writer can still be set from within an element handler, using setWriter(), but it must now be explicitly reset using resetWriter(). The writer is no longer directly associated with an element: a single element handler can therefore stack new writers and unstack them at will. This is useful when you want to write to multiple output streams from the same element handler. To achieve the equavalent effect of statically-allocated writers in previous releases, the suggested approach is to use the ElementToAttributeConverter handler to write content to an attribute of the root element, which can then be read during the end document processing. Calls to setNullWriter() should be replaced by invoking the new element handler ElementSuppressor.
- The ElementInfo interface now supports forwards as well as backwards processing in the document; but when the Distributor is used (with serial processing of the document) any attempt to look ahead causes an exception. The range of methods supported by ElementInfo is substantially extended.
- The parameter substitution in the format() method and in the parameters to GroupRenderer has changed to be compatible with XSL syntax. Instead of writing "abc«elem/att»xyz", you must now write "abc{ancestor(elem)@att}xyz". The benefit is an increased flexibility in the expressions you can evaluate, though it still falls well short of the full XSL range of expressions.
- The setUserData() and getUserData() methods on ElementInfo have changed so that an arbitrary number of named user data objects can be associated with an element, not just one as previously. These methods therefore have an extra parameter, name.
- The static escape() method has been moved from Renderer class to the new Utility class.
- XSL-like stylesheets have been introduced. For details, see here.
- The Wanderer class is introduced as an alternative to Distributor. (Both inherit from Controller). The Wanderer differs from the Distributor in that it does not automatically recurse through the document; it only visits a specified element, and subsequent behaviour is up to the element handler. The element handler can call applyTemplates() to achieve the same effect as currently: or it can, for example, call applyTemplates() with a pattern to process only selected children. The ability to use the DOM (rather than SAX) as a serial input source to the Distributor is withdrawn; use the Wanderer instead.
- The element handler ElementToAttributeConverter has been extended so it can now write to an attribute of any ancestor element, including the root (not just the parent element as before).
- SAXON has been validated to work with the Oracle XML parser (SAX and DOM)
- A richer set of patterns has been introduced for use in setHandler() (and in XSL style sheets). The pattern can now include the "//" (ancestor) and "*" operators from XSL
- The COM/ActiveX interface to SAXON is no longer maintained. (However, it is perfectly feasible to integrate COM applications with SAXON by using the Java/COM bridging tools available either from Microsoft or SUN.)

## Changes in version 3.1 (1998-10-15)

- Fixed a bug in MultiHandler: the beforeGroup() method was calling the afterGroup() methods of the underlying handlers instead of their beforeGroup() methods.
- Added resetWriters() method to Distributor to complete the ability to reset the Distributor for a second pass over the document. (Thanks to Adrian Tivey for the suggestion.)
- Sun XML parsers (validating and non-validating) added to the list of named parsers in ParserManager.properties
- Added a -d option to Renderer to use the DOM (for testing purposes)
- Added DOMBuilder interface to allow a DOM implementation to be selected at run-time, via the ParserManager.properties file
- Provided three implementations of DOMBuilder, to use Docuverse, IBM xml4j, or Sun DOM implementations respectively.
- Changed error handling to avoid calling Locator after end of document: SAX does not allow this, and it crashed Sun's parser. Added setErrorHandler() interface to Distributor to allow a choice of SAXON error handling or user-defined error handling.
- New element handler supplied: ElementToAttributeConvertor
- New setDefaultWriter() method in Distributor.
- New getDistributor() method in ElementInfo.
- New getRoot() method in ElementInfo.
- New method disableChildren() for an element handler to switch off processing of child elements.
- Overhaul of attribute handling. The methods getExtendedAttribute() and setExtendedAttribute() are replaced by getAncestorAttribute(), setAncestorAttribute(), and setAttribute(). The changed name reflects a change in semantics: attribute values are now retained only so long as the owning element remains current. To retain a value with document scope, you can set an attribute on the root element.

## Changes in version 3.03 (1998-08-27)

- Three hours after I put the FreeDOM 3 version on the web, Don Park announced that FreeDOM was being replaced by DOM-SDK. SAXON 3.03 now works with DOM-SDK version 1.0PR1. No interface changes.
- A new sample program, ShowBooks2, is included to demonstrate use of the DOM with SAXON.

## Changes in version 3.01

- Minor documentation changes only; no code change

## Changes in version 3.0 (1998-07-26)

- setOption(BUILD_DOM) withdrawn. Instead, to build a DOM document use:
  app = new Distributor()
  Document doc = app.build();
  int r = app.run(doc);
- new resetHandlers() interface in Distributor. This allows you to make several passes with different sets of element handlers
- saxon.ini file replaced with ParserManager.properties. This now has a list of known SAX-compliant parsers built in. To specify a default parser, edit the file. You can also add other SAX-compliant parsers to the list.
- changed to work with FreeDOM 3

## Changes in version 2.0 (1998-06-16)

- Performance improvements (SAXON is now a factor of 2-to-3 faster)
- added variant write() and writeEscape() methods to ElementInfo
- added exception handling. Element handlers now have to catch/throw SAXException
- setErrorOutput() method in Distributor to collect diagnostics
- Renderer main program outputs elapsed time in milliseconds
- new interface setOption(); maintenance of character content as a pseudo-attribute
- is now optional (off by default); keeping a copy of attributes beyond startElement() is also optional.
- can now work in conjunction with FREEDOM. This builds the DOM, then does a depth first walk of the tree calling the application element handlers as usual, but with a reference to the underlying Element object in the DOM model
- minor bug fix: package name in sample ShowBooks program

Michael H. Kay
2 December 1999