| SAXONICA |
The atomic type constants (such as Type.STRING_TYPE) in class Type have been removed.
They have been replaced with constants (such as BuiltInAtomicType.STRING in class
BuiltInAtomicType.
The class Value no longer implements Expression. Instead, an expression that evaluates
to constant value is now represented by a Literal that encapsulates the Value. This simplifies
the implementation of Value and all its subclasses, and it also means that all the objects on an expression
tree can now contain location information and parent pointers, simplifying the manipulation of the tree. As a consequence
of this change, it has been possible to merge the class ComputedExpression and the interface
Expression into a single abstract class.
The hierarchy of SequenceIterator classes and interfaces has been changed. The interface
AxisIterator (which is returned by NodeInfo.iterateAxis()) is now reserved
for iterators that return nodes only. Several new methods are defined in this interface, designed to
allow implementations that return "wrapper" nodes to defer the construction of the wrapper until it
is actually needed. Default implementations of these methods can be copied from the class
net.sf.saxon.om.AxisIteratorImpl.
The concept of an atomizable iterator no longer exists: this was a previous attempt to allow construction
of nodes to be avoided when not required, and is superseded by the new mechanism. A client can now call
the atomize() method on the AxisIterator itself, to avoid materializing the node
when only its atomized value is required.
There has been some reorganization of the classes used to represent collations. Previously
the general-purpose Comparator class was widely used, which led to confusion as to which kind of
Comparator was needed in different places. The code now distinguishes two kinds of comparator:
a StringCollator, which represents a collation in the XPath sense and is used specifically to
compare strings, and an AtomicComparer, which is used to compare arbitrary atomic values (and which
may encapsulate a StringCollator when string comparison using a collation is called for). This
change affects some user-visible interfaces, for example the CollationURIResolver.
The class NamedCollation (an implementation of StringCollator) has been
introduced to represent a collation other than the default collation. It encapsulates a collation
URI and the StringCollator object used to perform the actual comparison. The URI is retained
so that the NamedCollation can be reconstructed, for example when compiled code
is executed.
The code for arithmetic expressions has been extensively reorganized. All arithmetic expressions
are now represented on the expression tree by one of two classes: ArithmeticExpression
or ArithmeticExpression10,
the latter being used only when backwards compatibility mode is in force. The ArithmeticExpression object
contains a reference to a Calculator object, which is not itself an expression, but is a helper object that
actually performs the computation. There are many different subclasses of Calculator for different operators
and combinations of operands. If the types of the operands are known early, then a specific Calculator can be
allocated at compile time; if not, a generic Calculator is used which examines the dynamic types of the operands
at run-time and invokes one of the specific Calculators accordingly. This reorganization should give a slight
speed-up to interpreted code, especially where static types can be inferred, but the main purpose is to enable the
Java code generator to do a good job in translating XPath arithmetic expressions to Java.
When the API for free-standing XPath expressions is used, an Executable object is
now created, which makes it possible to use extension functions such as saxon:evaluate()
that rely on the presence of an Executable.
When running XQuery with a non-schema-aware Configuration, the default construction mode in the static context has changed from "preserve" to "strip". In this situation, the input nodes will normally be untyped, and this choice ensures that if new document is constructed by the query, the output nodes will also be untyped.
There has been some reorganization of the classes used to represent atomic values, designed to bring the Java class hierarchy into closer alignment with the XPath type hierarchy:
The class DerivedAtomicValue, used for values belonging to a user-defined atomic type,
is no longer used; instead, the relevant primitive type is used, for example StringValue
or DoubleValue. The root AtomicValue class now contains a field giving the type
label so that subtypes can be distinguished. In consequence, the method getPrimitiveValue()
is no longer required, and has been removed.
The class RestrictedStringValue has been removed; strings belonging to subtypes of
xs:string (for example, xs:NCName) are now instances of StringValue.
All integers now belong to the abstract class IntegerValue, which has two concrete
implementation classes, Int64Value and BigIntegerValue.
NotationValue no longer inherits from QNameValue, instead both share
a common abstract superclass, QualifiedNameValue.
The classes GYearValue, GYearMonthValue, GMonthValue,
GMonthDayValue, and GDayValue
no longer inherit from DateValue. Instead they now share an abstract superclass GDateValue
which contains the shared code.
These changes mean that in most cases it is now possible to use Java tests such as
x instanceof DateTimeValue to
test whether an AtomicValue is an instance of xs:dateTime or one of its subtypes.
There are still one or two
exceptions to this, however: IntegerValue in the Java class hierarchy is not a subclass of
DecimalValue, while UntypedAtomicValue and AnyURIValue are both
implemented as subclasses of StringValue. It should also be noted that an atomic value is
not necessarily represented by an instance of the AtomicValue class: it might also on occasions
be represented, say, by a SequenceExtent of length one, or by a MemoClosure.
Before relying on the representation,
the method Value.reduce() should be used to simplify such representations.