In Xpath 3.1 we already have head(), tail(), and last()
But there is no function that produces the subsequence of all items of a sequence except the last one. There exists such a function in other programming languages. For example, in Haskell this is the init function.
And the last() function isn't the symmetric opposite of head() -- it doesn't give us the last item in a sequence, just its position. So we need another function: fn:heel() for this.
fn:init($sequence as item()*) as item()*
fn:heel($sequence as item()*) as item()?
init($seq) is a convenient shorthand for subsequence($seq, 1, count($seq) -1)
heel($seq) is a convenient shorthand for slice($seq, -1)
Examples:
fn:init(('a', 'b', 'c')) returns 'a', 'b'
fn:init(('a', 'b')) returns 'a'
fn:init('a') returns ()
fn:init(()) returns ()
fn:heel('a', 'b', 'c') returns 'c'
('a', 'b', 'c') => init() => heel() returns 'b'
It makes sense to have fn:init() and fn:heel() defined on arrays, too.
array:init($array as array(*)) as array(*)
array:heel($array as array(*)) as item()*
Examples:
array:init([1, 2, 3, 4, 5]) returns [1, 2, 3, 4]
array:init([1]) returns []
array:heel([1, 2, 3, (4, 5)]) returns (4, 5)
array:heel([()]) returns () (the empty sequence)
array:init([]) produces error
array:heel([]) produces error
[1, 2, 3, (4, 5)] =>array:heel() => heel() returns 5
I would challenge anyone to re-write the last example in understandable way using fn:slice() 💯
In Xpath 3.1 we already have
head(),tail(), andlast()But there is no function that produces the subsequence of all items of a sequence except the last one. There exists such a function in other programming languages. For example, in Haskell this is the init function.
And the
last()function isn't the symmetric opposite ofhead()-- it doesn't give us the last item in a sequence, just its position. So we need another function:fn:heel()for this.init($seq)is a convenient shorthand forsubsequence($seq, 1, count($seq) -1)heel($seq)is a convenient shorthand forslice($seq, -1)Examples:
fn:init(('a', 'b', 'c'))returns'a', 'b'fn:init(('a', 'b'))returns'a'fn:init('a')returns()fn:init(())returns()fn:heel('a', 'b', 'c')returns'c'('a', 'b', 'c') => init() => heel()returns'b'It makes sense to have
fn:init()andfn:heel()defined on arrays, too.Examples:
array:init([1, 2, 3, 4, 5])returns[1, 2, 3, 4]array:init([1])returns[]array:heel([1, 2, 3, (4, 5)])returns(4, 5)array:heel([()])returns()(the empty sequence)array:init([])produces errorarray:heel([])produces error[1, 2, 3, (4, 5)] =>array:heel() => heel()returns5I would challenge anyone to re-write the last example in understandable way using
fn:slice()💯