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()*)+





The input sequence to be grouped



function(item()) as xs:boolean

The condition determining whether an item starts a new group




Notes on the Saxon implementation

Available since Saxon 9.9.


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.