Arrays are defined in the XDM Data Model.
The instruction xsl:array
constructs and returns a new array.
<!-- Category: instruction -->
<xsl:array
select? = expression
composite? = boolean >
<!-- Content: sequence-constructor -->
</xsl:array>
If the composite
attribute is omitted or set to no
, the resulting
array has one singleton member for each item returned by the select
attribute or
sequence constructor. For example <xsl:array select="1 to 5"/>
returns
an array with five members: [1, 2, 3, 4, 5]
.
If the composite
attribute is present with the value yes
, then
each item returned by the select
attribute or
sequence constructor must be an zero-arity function, and the sequences that result from
the evaluation of these zero-arity functions become the members of the array. For example,
<xsl:array select="function(){1 to 3}, function(){8 to 10}" composite="yes"/>
returns an array with two members: [(1,2,3), (8,9,10)]
.
The select
attribute and the contained sequence constructor are mutually
exclusive: if the select
attribute is present, then the only permitted child
element is xsl:fallback
.
For convenience and readability, the instruction xsl:array-member
can be used to construct a zero-arity function suitable for use with xsl:array
.
<!-- Category: instruction -->
<xsl:array-member
select? = expression >
<!-- Content: sequence-constructor -->
</xsl:array-member>
For example:
<xsl:array composite="yes"> <xsl:for-each select="'jane', 'mary', 'pete', 'andy'"> <xsl:array-member select="lower-case(.), upper-case(.)"/> </xsl:for-each> </xsl:array>
The result of this instruction is the array [('jane', "JANE"), ('mary', 'MARY'), '('pete', 'PETE'), ('andy', 'ANDY')]
:
that is, an array with four members, each of which is a sequence of two items.
Although the syntax is designed to be intuitive, the underlying mechanism is non-obvious. The effect of the
xsl:array-member
instruction is to return a zero-arity anonymous function which, on evaluation,
delivers the result of its select
attribute or contained sequence constructor. That is, the
xsl:array-member
instruction in this example is actually equivalent to:
<xsl:sequence select="let $member := (lower-case(.), upper-case(.)) return function(){$member}"/>
Specifically, the xsl:array-member
instruction evaluates its select
expression or contained sequence constructor (which are mutually exclusive),
to obtain a value V, and returns a zero-arity anonymous function
with signature function() as item()*
, which when invoked returns V.
Note:
The reason for this rather obscure formulation is to prevent the flattening of nested sequences that would normally occur when instructions within a sequence constructor deliver sequences rather than individual items. Wrapping the individual sequences within anonymous functions prevents this flattening.
More formally, the semantics of the xsl:array
instruction are as follows:
When there is no composite
attribute, or when composite="no"
:
The select
expression or contained sequence constructor
is evaluated, in the same way as for the xsl:sequence
instruction,
to yield a value V.
An array is constructed, containing one member for each item in V, whose value is that item.
This array is returned as the result of the xsl:array
instruction.
When composite="yes" is specified
:
The select
expression or contained sequence constructor
is evaluated, in the same way as for the xsl:sequence
instruction,
to yield a value V.
A type error is raised if V is not an instance of
(function() as item()*)*
. [TODO: add error code]
An array is constructed, containing one member for each item $v
in V, the value of the array member being $v()
.
This array is returned as the result of the xsl:array
instruction.
The semantics of the xsl:array-member
instruction are as follows:
The select
expression or contained sequence constructor
is evaluated, in the same way as for the xsl:sequence
instruction,
to yield a value V.
The xsl:array-member
instruction returns a zero-arity anonymous
function with signature function() as item()*
, whose evaluation
returns V.
The select
attribute and the contained sequence constructor of xsl:array
are mutually exclusive [Error condition TBA].
The select
attribute and the contained sequence constructor of xsl:array-member
are mutually exclusive [Error condition TBA].
Note:
XPath offers two constructs for creating arrays, the so called square and curly array constructors.
The square array constructor (for example [1, 3, 5, (7 to 10)]
can only construct an array where
the number of members is statically known (in this case there are four members). The curly array constructor
(for example array{1, 3, 5, (7 to 10)}
can only construct an array whose members are singleton items
(in this case there are seven members, each being a single integer).
The combination of
xsl:array
and xsl:array-member
, by contrast, can deliver an array
whose size is determined dynamically and whose members can be arbitrary XDM values.
An equivalent construct using array functions would be ['jane', 'mary', 'pete', 'andy'] =>
array:for-each(function($s){lower-case($s), upper-case($s)})
.