saxon:group-starting
Splits a sequence of items into a sequence of groups, each represented as an array; a new array starts whenever an item is found that matches a condition, which is supplied as a function.
group-starting($input as item()*, $condition as function(item()) as xs:boolean) ➔ array(item()*)+
Arguments | |||
| $input | item()* | The input sequence to be grouped |
| $condition | function(item()) as xs:boolean | The condition determining whether an item starts a new group |
Result | array(item()*)+ |
Namespace
http://saxon.sf.net/
Notes on the Saxon implementation
Available since Saxon 9.9.
Details
Like the xsl:for-each-group/@group-starting-with
instruction, this function partitions a sequence
based on splitting the sequence at any item that matches some predicate. The function can sometimes be a useful
alternative to the XSLT instruction, but it is primarily provided to bring similar functionality for non-XSLT
environments.
The function takes two arguments: the first argument is an arbitrary sequence; the second is a predicate function that takes a single item as input and returns a boolean. This predicate function is applied to each item in the sequence to decide whether it is a "matching" or "non-matching" item.
The result of the saxon:group-starting
function is a sequence of arrays. The first array (which is always present and may be empty) contains all the items from
the input sequence that precede the first matching item; subsequent arrays (one per matching item, always non-empty)
contain a matching item followed by zero or more non-matching items.
So the function call saxon:group-starting(1 to 10, fn{. mod 3 eq 0})
returns the sequence
([1,2], [3,4,5], [6,7,8], [9])
.
Similarly saxon:group-starting(1 to 10, fn{. mod 3 eq 1})
returns the sequence
([], [1,2,3], [4,5,6], [7,8,9])
.
Note that (as with fn:filter()
the predicate function must return a boolean, or a value
that can be converted to a boolean by the function conversion rules. Returning a node and relying on
the effective boolean value of a node being true does not work.
So the function call saxon:group-starting(following-sibling::*, fn{boolean(self::h1)})[1]?*
selects the following-sibling elements of the context item up to (and excluding) the first h1
element. The call on boolean()
here is necessary.
The function is pipelined in that it only scans the input to find one group at a time, on demand. Each group, however, is materialized as an array in memory.