This section describes how XPath values supplied in a call to an extension function are converted to Java values.
The following conversions are supported between the static type of the supplied value of the argument, and the declared Java class of the argument. The mappings are given in order of preference; a class that appears earlier in the list has smaller "conversion distance" than one appearing later. These priorities are used to decide which method to call when the class has several methods of the same name. Simple classes (such as boolean) are acceptable wherever the corresponding wrapper class (Boolean) is allowed. Class names shown in italics are Saxon-specific classes.
If the static type of the supplied value allows a sequence of more than one item, then Saxon looks for a method
that expects a SequenceIterator
, a SequenceValue
, a Collection
, or
a DOM NodeList
, in that order. (The first two classes are Saxon-specific). In these cases the item
type of the supplied value plays no role.
Nodes in the supplied sequence are atomized only if the Java method requires an atomic type such as an integer
or string. If the method requires a Collection, then the contents of the sequence will be supplied as is. The objects in
the List will typically be Saxon Item
objects. (Saxon does not yet recognize the generic types in JDK 1.5,
which allow the item type of a collection to be declared). If atomization is required, you can force it by calling the
data()
function.
If the required type is an array, Saxon will attempt to create an array of the required type. This will not always succeed,
for example if the array has type X[]
where X is an interface rather than a concrete class. If it is an array of items
or nodes, the nodes in the supplied sequence will be inserted into the array directly; if it is an array of a type such as
integer or
double, the sequence will first be atomized.
If the supplied value is a singleton (a sequence of one item) then the type of that item is decisive. If it is a sequence of length zero or more than one, then the general rules for a sequence are applied, and the types of the items within the sequence are irrelevant.
If the supplied value contains more than item and only a single item is expected, an error is reported. There is no implicit extraction of the first value (as happened in earlier releases).
Supplied type |
Required type |
boolean |
BooleanValue, Boolean |
dateTime |
DateTimeValue, Date |
date |
DateValue, Date |
decimal |
DecimalValue, BigDecimal, Double, Float |
double |
DoubleValue, Double |
duration |
DurationValue |
float |
FloatValue, Float, Double |
integer |
IntegerValue, BigInteger, BigDecimal, Long, Integer, Short, Byte, Double, Float |
string |
StringValue, (String, CharSequence) |
anyURI |
AnyURIValue, java.net.URI, java.net.URL, (String, CharSequence) |
QName |
QNameValue, javax.xml.namespace.QName |
node |
SingletonNodeSet, NodeList, (Element, Attr, Document, DocumentFragment, Comment, Text, ProcessingInstruction, CharacterData), Node, Boolean, Byte, Character, Double, Float, Integer, Long, Short, (String, CharSequence), Object |
sequence |
SequenceIterator, SequenceValue, List, NodeList, NodeInfo, Node, (String, CharSequence), Boolean, Byte, Character, Double, Float, Integer, Long, Short, Object |
Saxon tries to select the appropriate method based on the static type of the arguments to the function call. If there are several candidate methods, and there is insufficient information available to decide which is most appropriate, an error is reported. The remedy is to cast the arguments to a more specific type.
When the required type is a DOM Node or NodeList, and the supplied value is a sequence containing nodes, Saxon creates
a wrapper around each supplied node so that it implements the org.w3.dom.Node
interface. (However, if the
Saxon node is already a wrapper for a DOM Node, then the underlying DOM node is supplied.) Note that this is a read-only
DOM implementation: any attempt to update nodes through the wrapper interface will throw an exception.
A consequence of the way the
wrapping works is that it's not safe to rely on object identity when testing node identity - the same node can be represented
by
more than one Java object. Use the DOM method isSameNode()
instead.
If the supplied value is a wrapped Java object, which typically happens when it is itself the result of another extension function, then it may be converted to another data type as follows.
It is converted to a string by using its toString() method; if the object is null, the result is the empty string "".
It is converted to a number by converting it first to a string, and then applying the XPath number() conversion. If it is null, the result is NaN.
It is converted to a boolean as follows: if it is null, the result is false, otherwise it is converted to a string and the result is true if and only if the string is non-empty.