Converting method arguments - general rules
Having decided which method to call, Saxon has to convert the supplied XPath argument values to the Java objects required by this method.
The conversion is done as follows:
If there is an equivalent XPath type to the declared type of the Java method or constructor, then the supplied value is first converted to this equivalent XPath type using the standard function conversion rules used in all XPath function calls (without 1.0 backwards compatibility mode): for example an untyped attribute node can be supplied to a function that expects a string. The conversion from the equivalent XPath type to the actual Java type is then trivial, for example an
xs:string
value is converted to the correspondingjava.lang.String
.The equivalent XPath type is determined as follows:
If the Java class is an array of X, then the equivalent XPath type is T*, where T is the equivalent type to X. (For example
String[]
maps toxs:string*
)If the Java class is one of the Saxon classes
One<X>
,ZeroOrOne<X>
,OneOrMore<X>
, orZeroOrMore<X>
, then the equivalent XPath type is the equivalent type to X, with an appropriate occurrence indicator. For exampleOneOrMore<String>
maps toxs:string+
.If the Java class is a Saxon class used to implement items, such as
net.sf.saxon.value.StringValue
ornet.sf.saxon.om.NodeInfo
, then the equivalent XPath type is the XPath item type that this Java class implements.If the Java class is one of those listed in the table below, the equivalent XPath type is taken from this table:
Java class Equivalent XPath type boolean
xs:boolean
Boolean
xs:boolean?
String
xs:string?
CharSequence
xs:string?
net.sf.saxon.str.UnicodeString
xs:string?
long
xs:integer
Long
xs:integer?
int
xs:integer
Integer
xs:integer?
short
xs:short
Short
xs:short?
byte
xs:byte
Byte
xs:byte?
float
xs:float
Float
xs:float?
double
xs:double
Double
xs:double?
URI
xs:anyURI?
URL
xs:anyURI?
BigInteger
xs:integer?
BigDecimal
xs:decimal?
-
Where there is no equivalent XPath type, the following rules apply:
If the expected type is
Object
, the supplied value must either be a singleton, or an empty sequence. If it is an empty sequence, null will be passed. If it is a singleton node, an instance of net.sf.saxon.om.NodeInfo will be passed. If it is a wrapped Java object, that Java object will be passed. If it is a singleton atomic value, the value will be converted to the nearest equivalent Java object: for example anxs:boolean
becomesjava.lang.Boolean
, anxs:string
becomesjava.lang.String
, and so on. An untyped atomic value is treated as a string. Anxs:integer
(even if it belongs to a subtype such asxs:short
) is converted to a JavaBigInteger
. The more specialized XML Schema primitive types such asxs:hexBinary
andxs:duration
are passed in their native Saxon representation (a subclass of net.sf.saxon.value.AtomicValue).If the expected type is one of the Saxon-specific classes (SequenceIterator, Sequence, Item, AtomicValue, SequenceExtent), then the value is passed unchanged. An error occurs if the supplied value contains more than one item and the expected type does not allow this.
The types ZeroOrMore, OneOrMore, ZeroOrOne, and One can be used to specify the permitted cardinality, and can also be parameterized to define the permitted item type. For example, an argument defined as
One<StringValue>
is equivalent to the XPath SequenceTypestring
, and allows a single string only. When such declarations are used, the conversion of the supplied argument to the required type follows the standard XPath conversion rules precisely.If the expected type implements
java.util.Collection
, Saxon attempts to convert each value in the supplied sequence to the most appropriate Java class, following the same rules as when converting a singleton tojava.lang.Object
. This process takes no account of parameterized collection types (such asList<String>
). If the required collection type accepts anjava.util.ArrayList
, Saxon will create anArrayList
to hold the values; otherwise it will attempt to instantiate the required type of collection, which will only work if it is a concrete class with a zero-argument public constructor (so it will fail, for example, if the required type isjava.util.Set
). If an empty sequence is supplied as the argument value, this is converted to an emptyCollection
.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[]
whereX
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.