Main Page » XQuery » Functions » Standard Functions

Standard Functions

This page presents selected functions of the standard that have been added or changed in a recent version of the language, that are mentioned somewhere else in this documentation, or for which we want to give you BaseX-specific information. For the complete picture, you can visit the following resources:

Conventions

All functions and errors are assigned to the http://www.w3.org/2005/xpath-functions namespace, which is statically bound to the fn prefix.

Strings

fn:char

Added: New 4.0 function, replacing string:tab, string:nl and string:cr.

Signature
fn:char(
  $value  as (xs:string | xs:positiveInteger)
) as xs:string
SummaryReturns a single-character string for the specified $value, which can be:
Examples
char(65), char(0x41), char(0b01000001)
Result: 'A', 'A', 'A'
char('xcirc')
Result: '◯'
string-join(('auml', 'ouml', 'uuml', 'szlig') ! char(.))
Result: 'äöüß'
string-to-codepoints(char('\t'))
Result: 9

fn:characters

Signature
fn:characters(
  $value  as xs:string?
) as xs:string*
SummaryReturns the single characters of $value as a string sequence. Equivalent to:
for $cp in string-to-codepoints($value)
return codepoints-to-string($cp)
Examples
characters('AB')
Result: 'A', 'B'

fn:contains-token

Signature
fn:contains-token(
  $value      as xs:string*,
  $token      as xs:string,
  $collation  as xs:string?  := fn:default-collation()
) as xs:boolean
SummaryThe supplied strings will be tokenized at whitespace boundaries. The function returns true if one of the strings equals the supplied token, possibly under the rules of a supplied collation.
Examples
contains-token(('a', 'b c', 'd'), 'c')
Result: true()

fn:replace

Updated: Action parameter added.

Signature
fn:replace(
  $value        as xs:string?,
  $pattern      as xs:string,
  $replacement  as xs:string?                                             := (),
  $flags        as xs:string?                                             := '',
  $action       as (fn(xs:untypedAtomic, xs:untypedAtomic*) as item()?)?  := ()
) as xs:string
SummarySearches the regular expression $pattern in $value and performs a $replacement, using optional $flags. Instead of the replacement string, an $action can be specified for more sophisticated replacements.
Examples
replace('a1c', '\d', 'X')
Result: 'aXc'
replace('1aBc2', '[a-z]', 'X', 'i')
Result: '1XXX2'
replace('1aBc2', '[a-z]', action := upper-case#1)
Result: '1ABC2'
replace("Chapter 9", "[0-9]+", action := fn($match) { $match + 1 })
Result: 'Chapter 10'
replace(
  "12°34′57″",
  "([0-9]+)°([0-9]+)′([0-9]+)″",
  action := fn($full-match, $groups) {
    message($full-match),
    ($groups[1] + $groups[2] ÷ 60 + $groups[3] ÷ 3600) || '°'
  }
)
Result: '12.5825°'. Creates debugging output for the current match.

fn:tokenize

Updated: Action parameter added.

Signature
fn:tokenize(
  $value    as xs:string?,
  $pattern  as xs:string?  := (),
  $flags    as xs:string?  := ''
) as xs:string*
SummarySplits $value into several substrings wherever the regular expression $pattern is found, or (if no pattern is supplied) at whitespace boundaries.
Examples
tokenize('a b c')
Result: 'a', 'b', 'c'
tokenize('a, b,  c', ',\s*')
Result: 'a', 'b', 'c'
tokenize('a|b|c', '|', 'q')
Result: 'a', 'b', 'c'. Literal pattern search.

fn:string-join

Updated: Action parameter added.

Signature
fn:string-join(
  $values     as xs:anyAtomicType*,
  $separator  as xs:string?         := ''
) as xs:string
SummaryCreates a string by concatenating the supplied $values, optionally interspersed by a $separator.
Examples
string-join(1 to 3)
Result: '123'
string-join(('one', 'two', 'three'), ', ')
Result: 'one, two, three'

fn:collation-key

Added: New function.

Signature
fn:collation-key(
  $value      as xs:string,
  $collation  as xs:string?  := fn:default-collation()
) as xs:string
SummaryReturns a binary item for $value, using the supplied $collation, which can be used for unambiguous and context-free comparisons.
Examples
for value $v in map:build(
  ('a', 'A', 'b'),
  collation-key(?, collation({ 'strength': 'primary' })),
  identity#1
)
return [ $v ]
The result:
[ "b" ]
[ ("a", "A") ]

string-join(('one', 'two', 'three'), ', ')
Result: 'one, two, three'

Numbers

fn:is-NaN

Signature
fn:is-NaN(
  $value  as xs:anyAtomicType
) as xs:boolean*
SummaryReturns true if the argument is the xs:float or xs:double value NaN.
Examples
is-NaN(0e0 div 0)
Result: true()
is-NaN('NaN')
Result: false()

fn:random-number-generator

Signature
fn:random-number-generator(
  $seed  as xs:anyAtomicType?  := ()
) as map(xs:string, item())
SummaryCreates a random number generator, using an optional seed. The returned map contains three entries:
  • number is a random double between 0 and 1
  • next is a function that returns another random number generator
  • permute is a function that returns a random permutation of its argument
The returned random generator is deterministic: If the function is called twice with the same arguments and in the same execution scope, it will always return the same result.
Examples
let $rng := random-number-generator()
let $number := $rng?number                (: random number :)
let $next-rng := $rng?next()              (: new generator :)
let $next-number := $next-rng?number      (: another random number :)
let $permutation := $rng?permute(1 to 5)  (: random permutation of (1 to 5) :)
return ($number, $next-number, $permutation)

Nodes

fn:transitive-closure

Added: New 4.0 function.

Signature
fn:transitive-closure(
  $node  as node()?,
  $step  as fn(node()) as node()*
) as node()*
SummaryComputes the transitive closure of $node by applying $step to each unchecked node and returns all the nodes except for the input node.
Examples
let $nodes := <xml>
  <node id='0'/>
  <node id='1' idref='0'/>
  <node id='2' idref='1'/>
  <node id='3' idref='1'/>
</xml>/node
return transitive-closure(
  head($nodes),
  fn($n) { $nodes[@idref = $n/@id] }
)
The result:
<node id='1' idref='0'/>,
<node id='2' idref='1'/>,
<node id='3' idref='1'/>

fn:distinct-ordered-nodes

Signature
fn:distinct-ordered-nodes(
  $nodes  as node()*...
) as node()*
SummaryReturns nodes in distinct document order: duplicate nodes (nodes with the same node identity) are removed, and the remaining nodes are returned in document order. This function makes explicit what the path expression does before returning the result of a node traversal. It is equivalent to expressions like:
$nodes/self::node()
$nodes/.
$nodes union .
$nodes except ()
Examples
let $doc := <doc><b/><a/></doc>
return distinct-ordered-nodes($doc/a, $doc/a, $doc/b)
Result: <b/>, <a/>

fn:in-scope-namespaces

Added: New 4.0 function.

Signature
fn:in-scope-namespaces(
  $element  as element()
) as map((xs:NCName | enum('')), xs:anyURI)
SummaryReturns the in-scope namespaces of $element as a map.
Examples
in-scope-namespaces(<xsi:a/>)
The result:
{
  "xsi": "http://www.w3.org/2001/XMLSchema-instance",
  "xml": "http://www.w3.org/XML/1998/namespace"
}

URIs

fn:encode-for-uri

Signature
fn:encode-for-uri(
  $value  as xs:string?
) as xs:string
SummaryEscapes characters in $value for use in a URI.
Examples
encode-for-uri('São Paulo?')
Result: 'S%C3%A3o%20Paulo%3F'
encode-for-uri('ABC123-~._ !"#<=>?')
Result: ABC123-~._%20%21%22%23%3C%3D%3E%3F

fn:decode-from-uri

Added: New 4.0 function.

Signature
fn:decode-from-uri(
  $value  as xs:string?
) as xs:string
SummaryDecodes URI-escaped characters in $value.
Examples
decode-from-uri('S%C3%A3o%20Paulo%3F')
Result: 'São Paulo?'
decode-from-uri('%00')
Result: . Invalid characters are replaced with the Unicode replacement character FFFD.

Comparisons

fn:atomic-equal

Added: New 4.0 function.

Signature
fn:atomic-equal(
  $value1  as xs:anyAtomicType,
  $value2  as xs:anyAtomicType
) as xs:boolean
SummaryDetermines whether the atomic values $value1 and $value2 are equal.
Examples
atomic-equal(1, 1.0)
Result: true()
atomic-equal('a', xs:anyURI('a'))
Result: true()
atomic-equal(xs:double('NaN'), xs:double('NaN'))
Result: true()
atomic-equal(1, '1')
Result: false()

fn:deep-equal

Updated: Options argument added.

Signature
fn:deep-equal(
  $input1   as item()*,
  $input2   as item()*,
  $options  as (xs:string | map(*))?  := { 'collation': default-collation() }
) as xs:boolean
SummaryDetermines if $input1 and $input2 are deep-equal. The $options can be either a string, denoting a collation, or a options map:
optiondefaultdescription
base-urifalse()Consider base-uri of nodes.
collationdefault-collation()Collation to be used.
commentsfalse()Consider comments.
id-propertyfalse()Consider id property of elements and attributes.
idrefs-propertyfalse()Consider idrefs property of elements and attributes.
in-scope-namespacesfalse()Consider in-scope namespaces.
items-equalvoid#0Custom function to compare items. If an empty sequence is returned, the standard comparison is applied.
namespace-prefixesfalse()Consider prefixes in QNames.
nilled-propertyfalse()Consider nilled property of elements and attributes.
normalization-form()Applies Unicode normalization to strings. Allowed values are NFC, NFD, NFKC, NFKD and FULLY-NORMALIZED.
orderedtrue()Considers the top-level order of the input sequences.
processing-instructionsfalse()Consider processing instructions.
timezonesfalse()Consider timezones in time/date values.
unordered-elements()A list of QNames of elements considered whose child elements may appear in any order.
whitespacepreserveHandling of whitespace:
  • preserve: Compare strings unchanged.
  • strip: Ignore whitespace-only text nodes.
  • normalize: Normalize whitespace; ignore whitespace-only text nodes.
Examples
deep-equal((), ())
Result: true()
deep-equal(1, 1.0)
Result: true()
deep-equal(
  <name sex='f' id='name1'>Sunita</name>,
  <name id="name1" sex="f">Sunita</name>
)
Result: true(). Attributes have no order, different quotes make no difference.
deep-equal((1, 2, 3), (3, 2, 1), { 'ordered': false() })
Result: true()
deep-equal('X', ' X ', { 'whitespace': 'normalize' })
Result: true()
deep-equal(sum#1, sum#2, {
  'items-equal': fn($a, $b) {
    if(($a, $b) instance of fn()) {
      function-name($a) = function-name($b)
    }
  }
})
Result: true(). When comparing functions, only the function name is considered, but not the arity.

fn:compare

Updated: Generalized to accept types other than strings.

Signature
fn:compare(
  $value1     as xs:anyAtomicType?,
  $value2     as xs:anyAtomicType?,
  $collation  as xs:string?         := fn:default-collation()
) as xs:integer?
SummaryReturns -1, 0, or 1, depending on whether $value1 is less than, equal to, or greater than $value2, and using the specified $collation for strings.
Examples
compare(1, 1.0)
Result: 0
compare(xs:double('NaN'), 0)
Result: -1
compare('a', 'A')
Result: 1
compare(
  'Strasse',
  'Straße',
  collation({ 'lang': 'de', 'strength': 'primary' })
)
Result: 0
compare(xs:hexBinary('41'), xs:base64Binary('QQ=='))
Result: 0

fn:starts-with-subsequence

Added: New 4.0 function.

Signature
fn:starts-with-subsequence(
  $input        as item()*,
  $subsequence  as item()*,
  $compare      as (fn(item(), item()) as xs:boolean)?  := fn:deep-equal#2
) as xs:boolean
SummaryDetermines whether $input starts with $subsequence, using the $compare function to compare items.
Examples
starts-with-subsequence(1 to 10, 1 to 3)
Result: true()
starts-with-subsequence(1 to 10, ('a', 'bb', 'ccc'), fn($a, $b) { $a = string-length($b) })
Result: true()

fn:ends-with-subsequence

Added: New 4.0 function.

Signature
fn:ends-with-subsequence(
  $input        as item()*,
  $subsequence  as item()*,
  $compare      as (fn(item(), item()) as xs:boolean)?  := fn:deep-equal#2
) as xs:boolean
SummaryDetermines whether $input ends with $subsequence, using the $compare function to compare items.
Examples
ends-with-subsequence(1 to 10, 8 to 10)
Result: true()
ends-with-subsequence(
  ('one', 'two', 'three'),
  ('t', 't'),
  starts-with#2
)
Result: true()

fn:contains-subsequence

Added: New 4.0 function.

Signature
fn:contains-subsequence(
  $input        as item()*,
  $subsequence  as item()*,
  $compare      as (fn(item(), item()) as xs:boolean)?  := fn:deep-equal#2
) as xs:boolean
SummaryDetermines whether $input contains $subsequence, using the $compare function to compare items.
Examples
contains-subsequence(1 to 10, 4 to 6)
Result: true()
contains-subsequence(
  ('anna', 'berta', 'clara', 'dora'),
  ('CLARA', 'DORA'),
  fn($a, $b) { $a = lower-case($b) }
)
Result: true()

fn:all-equal

Added: New 4.0 function.

Signature
fn:all-equal(
  $values     as xs:anyAtomicType*,
  $collation  as xs:string?         := fn:default-collation()
) as xs:boolean
SummaryReturns true if all items in $values are equal, using the specified $collation for string comparisons.
Examples
all-equal((1, 1.0, 1e0))
Result: true()
all-equal((1, '1'))
Result: false()
all-equal(())
Result: true()

fn:all-different

Added: New 4.0 function.

Signature
fn:all-different(
  $values     as xs:anyAtomicType*,
  $collation  as xs:string?         := fn:default-collation()
) as xs:boolean
SummaryReturns true if all items in $values are distinct, using the specified $collation for string comparisons.
Examples
all-different(1 to 5)
Result: true()
all-different(())
Result: true()

fn:every

Added: New 4.0 function.

Signature
fn:every(
  $input      as item()*,
  $predicate  as (fn(item(), xs:integer) as xs:boolean)?  := fn:boolean#1
) as xs:boolean
SummaryReturns true if every item in $input matches $predicate. If no predicate is specified, the boolean value of the item will be checked.
Examples
every(1 to 5)
Result: true()
every(1 to 5, fn { . > 3 })
Result: false()
every(())
Result: true()

fn:some

Added: New 4.0 function.

Signature
fn:some(
  $input      as item()*,
  $predicate  as (fn(item(), xs:integer) as xs:boolean)?  := fn:boolean#1
) as xs:boolean
SummaryReturns true if some items in $input match $predicate. If no predicate is specified, the boolean value of the item will be checked.
Examples
some(-3 to 3)
Result: true()
every(1 to 5, fn { . > 3 })
Result: false()
some(())
Result: false()

fn:index-where

Added: New 4.0 function.

Signature
fn:index-where(
  $input      as item()*,
  $predicate  as fn(item(), xs:integer) as xs:boolean
) as xs:integer*
SummaryReturns the positions of all items of $input that match the $predicate function.
Examples
index-where(
  (10, 11, 12, 14, 17, 21, 26),
  fn { . mod 2 = 0 }
)
Result: 1, 3, 4, 7
index-where(
  (1, 8, 2, 7, 3),
  fn($item, $pos) { $item < 5 and $pos > 2 }
)
Result: 3, 5

Sequences

fn:sort

Updated: Support for multipe sort key definitions.

Signature
fn:sort(
  $input       as item()*,
  $collations  as xs:string*                          := fn:default-collation(),
  $keys        as (fn(item()) as xs:anyAtomicType*)*  := fn:data#1,
  $orders      as enum('ascending', 'descending')*    := 'ascending'
) as item()*
SummaryReturns a new sequence with sorted $input items. Multipe $collations, $keys and $orders can be supplied, which will be applied on each sort items. The items resulting from the sort keys will be sorted using the semantics of the lt operator.
Examples
sort(reverse(1 to 3))
Result: 1, 2, 3
sort(1 to 3, orders := 'descending')
Result: 3, 2, 1
sort((-2, 1, 3), keys := abs#1)
Result: 1, -2, 3
sort($employees, (), (fn { @name }, fn { number(@age) }))
Sorts employees by their name and city.
sort((1, 'a'))
Raises an error because strings and integers cannot be compared.

fn:sort-with

Added: New 4.0 function.

Signature
fn:sort-with(
  $input        as item()*,
  $comparators  as (fn(item(), item()) as xs:integer)*
) as item()*
SummaryReturns a new sequence of $input with the order induced by the supplied $comparators.
Examples
sort-with((1, 4, 6, 5, 3), compare#2)
Result: 1, 3, 4, 5, 6
sort-with(
  (1, -2, 5, 10, -12, 8),
  fn($a, $b) { abs($a) - abs($b) }
)
Result: 1, -2, 5, 8, 10, -12
let $persons := <persons>
  <person name='Josipa' age='8'/>
  <person name='Jade' age='6'/>
  <person name='Jie' age='8'/>
</persons>
return sort-with($persons/person, (
  fn($a, $b) { compare($a/@age, $b/@age) },
  fn($a, $b) { compare($a/@name, $b/@name) }
))
The result:
<person name="Jade" age="6"/>,
<person name="Jie" age="8"/>,
<person name="Josipa" age="8"/>

fn:foot

Added: New 4.0 function, replacing util:last.

Signature
fn:foot(
  $input  as item()*
) as item()?
SummaryReturns the last item of $input. Equivalent to $value[last()].
Examples
foot(reverse(1 to 100))
Result: 1

fn:trunk

Added: New 4.0 function, replacing util:init.

Signature
fn:trunk(
  $input  as item()*
) as item()*
SummaryReturns all item of $input except for the last one. Equivalent to $value[position() < last()].
Examples
trunk(reverse(1 to 4))
Result: 4, 3, 2

fn:items-at

Added: New 4.0 function, replacing util:item.

Signature
fn:items-at(
  $input  as item()*,
  $at     as xs:integer*
) as item()*
SummaryReturns the items from $input at the positions specified with $at in the given order. Equivalent to:
for $pos in $at
return $input[$pos]
Examples
items-at(reverse(1 to 5), 1)
Result: 5
items-at(('one', 'two'), (2, 1))
Result: 'two', 'one'
items-at(('a', 'b'), 0)
Result: ()

fn:slice

Added: New 4.0 function.

Signature
fn:slice(
  $input  as item()*,
  $start  as xs:integer?  := (),
  $end    as xs:integer?  := (),
  $step   as xs:integer?  := ()
) as item()*
SummaryReturns a new version of $input starting from $start and ending at $end, using the specified $step:
  • If no start is specified, the sequence will start with the first item.
  • If no end is specified, all remaining items are returned.
  • If end is greater than start, the items are returned in reverse order.
  • If a negative start or end is specified, the counter start from the end of the sequence.
Examples
slice(1 to 5, 3)
Result: 3, 4, 5
slice(1 to 5, 3, 4)
Result: 3, 4
slice(1 to 10, -3)
Result: 8, 9, 10
slice(1 to 5, 4, 2)
Result: 4, 3, 2
slice(1 to 5, step := 2)
Result: 1, 3, 5

fn:remove

Updated: More than one position can now be specified.

Signature
fn:remove(
  $input      as item()*,
  $positions  as xs:integer*
) as item()*
SummaryReturns a new version of $input that excludes the items at the specified $positions.
Examples
remove(1 to 3, 2)
Result: 1, 3
remove(1 to 5, (5, 3, 1))
Result: 2, 4

fn:subsequence-where

Added: New 4.0 function, replacing hof:drop-while.

Signature
fn:subsequence-where(
  $input  as item()*,
  $from   as (fn(item(), xs:integer) as xs:boolean)?  := true#0,
  $to     as (fn(item(), xs:integer) as xs:boolean)?  := false#0
) as item()*
SummaryReturns a subsequence of $input starting with the first item that matches $from, and ending with the first subsequent item that matches $to.

The function is equivalent to:

let $start := index-where($input, $from)[1]             otherwise (count($input) + 1)
let $end   := index-where($input, $to)[. ge $start][1]  otherwise (count($input) + 1)
return slice($input, $start, $end)
Examples
subsequence-where(1 to 5, fn { . >= 3 })
Result: 3, 4, 5
subsequence-where(1 to 5, fn { . >= 2 }, fn { . >= 4 })
Result: 2, 3, 4
let $drop-while := fn($input, $predicate) {
  subsequence-where($input, fn { not($predicate(.)) })
}
return $drop-while(1 to 5, fn { . <= 2 })
Result: 3, 4, 5. The function can be used to emulate the nonexisting drop-while function.

fn:take-while

Added: New 4.0 function, replacing hof:take-while.

Signature
fn:take-while(
  $input      as item()*,
  $predicate  as fn(item(), xs:integer) as xs:boolean?
) as item()*
SummaryReturns items of $input as long as $predicate is satisfied. The predicate is called with the current item and position.

The function is equivalent to:

declare function take-while($input, $predicate, $pos := 1) {
  if(exists($input) and $predicate(head($input), $pos)) {
    head($input),
    take-while(tail($input), $predicate, $pos + 1)
  }
};
Examples
take-while((1, 5, 10, 20, 50, 100), fn { . <= 30 })
Returns all integers until a value is larger than 30.
take-while(
  (1 to 100) ! random:integer(50),
  fn($item, $pos) { . >= 10 }
)
Computes at most 100 random integers, but stops if an integer is smaller than 10.

fn:intersperse

Added: New 4.0 function, replacing util:intersperse.

Signature
fn:intersperse(
  $input      as item()*,
  $separator  as item()*
) as item()*
SummaryInserts a $separator between each item of $input. Equivalent to:
head($input), tail($input) ! ($separator, .)
Examples
(1 to 3)
=> intersperse('|')
=> string-join()
Result: '1|2|3'
intersperse((<_>1</_>, <_>2</_>, <_>3</_>), '; ')
Inserts semicolon strings between the three input items.

fn:replicate

Added: New 4.0 function, replacing util:replicate.

Signature
fn:replicate(
  $input  as item()*,
  $count  as xs:nonNegativeInteger
) as item()*
SummaryEvaluates $input and returns the result $count times.
Examples
replicate('A', 3)
Result: 'A', 'A', 'A'
let $nodes := replicate(<node/>, 2)
return $nodes[1] is $nodes[2]
true is returned, as two instances of the same node are returned.

fn:void

Added: New 4.0 function, replacing prof:void.

Signature
fn:void(
  $input  as item()*
) as empty-sequence()
SummaryAbsorbs $input and returns an empty sequence. This function is helpful if some (often nondeterministic or side-effecting) code needs to be evaluated and if the resulting value is not required
Examples
void(fetch:binary('http://my.rest.service'))
Performs an HTTP request and ignores the result.

Aggregrations

fn:highest

Added: New 4.0 function.

Signature
fn:highest(
  $input      as item()*,
  $collation  as xs:string?                       := fn:default-collation(),
  $key        as fn(item()) as xs:anyAtomicType*  := fn:data#1
) as item()*
SummaryReturns those items from $input for which $key produces the highest value, using the specified $collation for strings.
Examples
highest(8 to 12)
Result: 12
highest(98 to 102, key := string#1)
Result: 99
highest(1 to 7, (), fn { . idiv 3 })
Result: 6, 7

fn:lowest

Added: New 4.0 function.

Signature
fn:lowest(
  $input      as item()*,
  $collation  as xs:string?                       := fn:default-collation(),
  $key        as fn(item()) as xs:anyAtomicType*  := fn:data#1
) as item()*
SummaryReturns those items from $input for which $key produces the lowest value, using the specified $collation for strings.
Examples
lowest(8 to 12)
Result: 8
lowest(98 to 102, key := string#1)
Result: 100
lowest(1 to 7, (), fn { . idiv 3 })
Result: 1, 2

fn:duplicate-values

Added: New 4.0 function, replacing util:duplicates.

Signature
fn:duplicate-values(
  $values     as xs:anyAtomicType*,
  $collation  as xs:string?         := fn:default-collation()
) as xs:anyAtomicType*
SummaryReturns all values that appear in $values more than once. If no $collation is specified, the function is equivalent to:
for $group in $values
group by $value := $group
where count($group) > 1
return $value
Examples
duplicate-values((1, 2, 3, 1.0, 1e0))
Result: 1
duplicate-values(1 to 100)
Result: ()
let $ids := duplicate-values(//@id)
where exists($ids)
return error((), 'Duplicate IDs found: ' || string-join($ids, ', '))
Raises an error for duplicates in a sequence.

fn:partition

Added: New 4.0 function.

Signature
fn:partition(
  $input       as item()*,
  $split-when  as fn(item()*, item(), xs:integer) as xs:boolean
) as array(item())*
SummaryPartitions the $input into a sequence of non-empty arrays, starting a new partition when $split-when is true for a tested item.
Examples
partition((1 to 5), fn($seq) { count($seq) = 2 })
Result: [ 1, 2 ], [ 3, 4 ], [ 5 ]
partition(
  ('Anita', 'Anne', 'Barbara', 'Catherine', 'Christine'), 
  fn($partition, $next) {
    substring(head($partition), 1, 1) ne substring($next, 1, 1)
  }
)
The result:
[ 'Anita', 'Anne' ],
[ 'Barbara' ],
[ 'Catherine', 'Christine' ]

Input

fn:parse-integer

Added: New 4.0 function.

Signature
fn:parse-integer(
  $value  as xs:string,
  $radix  as xs:integer?  := 10
) as xs:integer
SummaryConverts $value to an integer, using the supplied $radix in the range 2 to 36. The input may be positive or negative and can contain whitespace and underscore separators.
Examples
parse-integer('7B', 16)
Result: 123
parse-integer('11111111', 2)
Result: 255
parse-integer(' -1_000_000 ')
Result: -1000000

fn:parse-QName

Added: New 4.0 function.

Signature
fn:parse-QName(
  $value  as xs:string
) as xs:QName
SummaryConverts $value to a QName. The supplied string can be a local name, have a namespace prefix, or use the braced URI syntax.
Examples
parse-QName('xml:node') => namespace-uri-from-QName()
Result: 'http://www.w3.org/XML/1998/namespace'
let $qname := parse-QName('Q{http://gotcha.org/works}fine')
return string-join((
  namespace-uri-from-QName($qname),
  local-name-from-QName($qname)
), ': ')
Result: 'http://gotcha.org/works: fine'

fn:parse-ietf-date

Signature
fn:parse-ietf-date(
  $value  as xs:string?
) as xs:dateTime?
SummaryParses a string in the IETF format (which is widely used on the Internet) and returns a xs:dateTime item:
Examples
parse-ietf-date('28-Feb-1984 07:07:07')
Result: xs:dateTime('1984-02-28T07:07:07Z')
parse-ietf-date('Wed, 01 Jun 2001 23:45:54 +02:00')
Result: xs:dateTime('2001-06-01T23:45:54+02:00')

fn:invisible-xml

Added: New 4.0 function.

A separate page is available on Invisible XML and how to use it in XQuery.

Output

fn:serialize

Signature
fn:serialize(
  $input    as item()*,
  $options  as (element(output:serialization-parameters) | map(*))?  := ()
) as xs:string
SummaryReturns a string representation of $input. The $options argument contains serialization parameters, which can be supplied…
  1. as a map…
    { "method": "xml", "cdata-section-elements": "div" }
  2. or (for backward compliance) as an element:
    <output:serialization-parameters>
      <output:method value='xml'/>
      <output:cdata-section-elements value='div'/>
    </output:serialization-parameters>
Examples
serialize(1 to 3)
Result: '1 2 3'
serialize(<xml id='1'></xml>)
Result: '<xml id="1"/>'
serialize(<html/>, { 'method': 'html', 'html-version': '5.0' })
Result: '<!DOCTYPE html><html></html>'
serialize({ 1: "one" }, { 'method': 'json' })
Result: '{"1":"one"}'

fn:format-integer

Updated: Support for formatting integers in a different radix.

Signature
fn:format-integer(
  $value     as xs:integer?,
  $picture   as xs:string,
  $language  as xs:string?   := ()
) as xs:string
SummaryConverts $value to a string, using the supplied $picture and (optionally) $language.
Examples
format-integer(123, '0')
Result: '123'
format-integer(12, 'w')
Result: 'twelve'
format-integer(21, 'Ww;o', 'de')
Result: 'Einundzwanzigste'
format-integer(65535, '16^xxxx')
Result: 'ffff'
format-integer(15, '2^xxxx')
Result: '1111'

fn:format-number

Updated: Easier definition of languages and decimal formats.

Signature
fn:format-number(
  $value    as xs:numeric?,
  $picture  as xs:string,
  $options  as (xs:string | map(*))?  := ()
) as xs:string
SummaryConverts $value to a string, using the supplied $picture and $options. The options argument can be the name of a statically available decimal-format or a set of options.
Examples
format-number(123, '0')
Result: '123'
format-number(1.23, '0,0##', 'de')
Result: '1,23'
format-number(1234, "0.000,0", { 'format-name': 'de' })
Result: '1.234,0'
format-number(1010, '0^0', { 'exponent-separator': '^' })
Result: '1^3'
format-number(1984.42, '00.0e0')
Result: '19.8e2'

fn:expanded-QName

Added: New 4.0 function.

Signature
fn:expanded-QName(
  $value  as xs:QName?
) as xs:string?
SummaryReturns a string representation of the QName $value in the format Q{uri}local.
Examples
expanded-QName(xs:QName('country'))
Result: 'Q{}country'
expanded-QName(QName('http://eat.org/lunch', 'cake'))
Result: 'Q{http://eat.org/lunch}cake'

JSON

Strings and resources can be parsed to XDM items and serialized back to their original form.

fn:parse-json

Signature
fn:parse-json(
  $value    as xs:string?,
  $options  as map(*)?     := {}
) as item()?
SummaryParses the supplied $value as a JSON string and returns an item representation, using the supplied $options. The result may be a map, an array, a string, a double, a boolean, or an empty sequence.
Examples
parse-json('{ "name": "john" }')
{ "name": "json" }.
parse-json('[ 1, 2, 4, 8, 16 ]')
[ 1, 2, 4, 8, 16 ].

fn:json-doc

Signature
fn:json-doc(
  $href     as xs:string?,
  $options  as map(*)?     := {}
) as item()?
SummaryParses the JSON string retrieved from the $href location and returns an item representation, using the supplied $options.
Examples
json-doc("http://ip.jsontest.com/")?id
Returns your IP address.

fn:json-to-xml

Signature
fn:json-to-xml(
  $value    as xs:string?,
  $options  as map(*)?     := {}
) as document-node()?
SummaryParses the supplied $value as a JSON string and returns an XML representation, using the supplied $options.
Examples
json-to-xml('{ "message": "world" }')
The result:
document {
  <map xmlns="http://www.w3.org/2005/xpath-functions">
    <string key="message">world</string>
  </map>
}

fn:xml-to-json

Signature
fn:xml-to-json(
  $node     as node()?,
  $options  as map(*)?  := {}
) as xs:string?
SummaryConverts a $node, whose format conforms to the results created by fn:json-to-xml, to a JSON string, using the supplied $options.
Examples
<map xmlns="http://www.w3.org/2005/xpath-functions">
  <string key="message">world</string>
</map>
=> xml-to-json()
Result: '{"message":"world"}'

Functions

fn:function-name

Signature
fn:function-name(
  $function  as fn(*)
) as xs:QName?
SummaryReturns the name of a $function item.
Examples
function-name(true#0)
Result: xs:QName('fn:true')
function-name(fn { . + 1 })
Result: ()

fn:function-arity

Signature
fn:function-arity(
  $function  as fn(*)
) as xs:integer
SummaryReturns the arity (number of parameters) of a $function item.
Examples
function-arity(true#0)
Result: 0
function-arity(fn { . + 1 })
Result: 1

fn:function-annotations

Added: New 4.0 function.

Signature
fn:function-annotations(
  $function  as fn(*)
) as map(xs:QName, xs:anyAtomicType*)
SummaryReturns the annotations of a $function item in a map.
Examples
declare
  %public
  %rest:GET
  %rest:path('/')
  %perm:allow('all')
function local:index($n) {
  <html>Welcome!</html>
};
function-annotations(local:index#1)
The result:
{
  QName('http://www.w3.org/2012/xquery', 'public'): (),
  QName('http://exquery.org/ns/restxq', 'GET'): (),
  QName('http://exquery.org/ns/restxq', 'path'): '/',
  QName('http://basex.org/modules/perm', 'allow'): 'all'
}

let $add := fn($a, $b) { $a * $b }
let $double := %local:deprecated fn($a) { $a + $a }
for $f in ($add, $double)
where map:keys(function-annotations($f)) = xs:QName('local:deprecated')
return 'Deprecated function found.'
Result: 'Deprecated function found.'

Higher-Order

fn:filter

Updated: Positional argument added to the function parameter.

Signature
fn:filter(
  $input      as item()*,
  $predicate  as fn(item(), xs:integer) as xs:boolean?
) as item()*
SummaryApplies the boolean $predicate to all elements of the sequence $input, returning those for which it returns true(). The function can easily be implemented with fn:for-each:
declare function filter($input, $pred) {
  for-each(
    $input,
    fn($item) { if ($pred($item)) { $item } }
  )
};

An equivalent XQuery function is:

declare function filter(
  $input      as item()*,
  $predicate  as fn(item()) as xs:boolean?
) as item()* {
  $input[$predicate(.)]
};
Examples
filter(1 to 10, fn { . mod 2 eq 0 })
Result: 2, 4, 6, 8, 10. Returns all even integers until 10.
let $first-upper := fn($str) {
  let $first := substring($str, 1, 1)
  return $first eq upper-case($first)
}
return filter(('FooBar', 'foo', 'BAR'), $first-upper)
Result: 'FooBar', 'BAR'. Returns strings that start with an upper-case letter.
let $is-prime := fn($x) {
  $x gt 1 and (every $y in 2 to ($x - 1) satisfies $x mod $y != 0)
}
return filter(1 to 20, $is-prime)
Result: 2, 3, 5, 7, 11, 13, 17, 19. An inefficient prime number generator.

fn:for-each

Updated: Positional argument added to the function parameter.

Signature
fn:for-each(
  $input   as item()*,
  $action  as fn(item(), xs:integer) as item()*
) as item()*
SummaryApplies the specified $action to every item of $input and returns all results as a single sequence.

An equivalent XQuery function is:

declare function for-each(
  $input   as item()*,
  $action  as fn(item()) as item()*
) as item()* {
  for $item in $input
  return $action($item)
}
Examples
for-each(1 to 10, math:pow(?, 2))
Result: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100. Computes the square of all numbers from 1 to 10.
let $fs := (
  upper-case#1,
  substring(?, 4),
  string-length#1
)
return for-each($fs, fn($f) { $f('foobar') })
Result: 'FOOBAR', 'bar', 6. Applies a list of functions to a string.
("one", "two", "three") => for-each(upper-case(?))
Result: 'ONE', 'TWO', 'THREE'. Processes each item of a sequence with the arrow operator.

fn:for-each-pair

Updated: Positional argument added to the function parameter.

Signature
fn:for-each-pair(
  $input1  as item()*,
  $input2  as item()*,
  $action  as fn(item(), item(), xs:integer) as item()*
) as item()*
SummaryApplies the specified $action to the successive pairs of items of $input1 and $input2. Evaluation is stopped if one sequence yields no more items.

An equivalent function is:

declare function for-each-pair(
  $input1  as item()*,
  $input2  as item()*,
  $action  as fn(item(), item()) as item()*
) as item()* {
  for $pos in 1 to min((count($input1), count($input2)))
  return $action($input1[$pos], $input2[$pos])
};
Examples
for-each-pair(
  for-each(1 to 10, fn { . mod 2 }),
  replicate(1, 5),
  fn($a, $b) { $a + $b }
)
Result: 2, 1, 2, 1, 2. Adds one to the numbers at odd positions.
let $number-words := fn($str) {
  string-join(
    for-each-pair(
      1 to 1000000000,
      tokenize($str, ' +'),
      concat(?, ': ', ?)
    ),
    ', '
  )
}
return $number-words('how are you?')
Result: '1: how, 2: are, 3: you?'
let $is-sorted := fn($input) {
  every $b in
    for-each-pair(
      $input,
      tail($input),
      fn($a, $b) { $a <= $b }
    )
  satisfies $b
}
return (
  $is-sorted(1 to 10),
  $is-sorted((1, 2, 42, 4, 5))
)
Result: true(), false(). Checks if a sequence is sorted.

fn:while-do

Added: New 4.0 function, replacing hof:until.

Signature
fn:while-do(
  $input      as item()*,
  $predicate  as fn(item()*, xs:integer) as xs:boolean,
  $action     as fn(item()*, xs:integer) as item()*
) as item()*
SummaryThis function provides a way to write functionally clean and interruptible iterations, commonly known as while loops:
  1. $predicate is called with $input.
  2. If the result is true, $action is called with $input, the result is adopted as new $input, and step 2 is repeated.
  3. Otherwise, $input is returned.
Examples
while-do(2, fn { . <= 100 }, fn { . * . })
Result: 256. The loop is interrupted as soon as the computed product is greater than 100.
while-do(
  1,
  fn($num, $pos) { $pos <= 10 },
  fn($num, $pos) { $num * $pos }
)
Result: 3628800. Returns the factorial of 10, i.e., the product of all integers from 1 to 10.
let $input := (0 to 4, 6 to 10)
return while-do(
  0,
  fn($n) { $n = $input },
  fn($n) { $n + 1 }
)
Result: 5. Returns the first positive number missing in a sequence.
let $input := 3936256
return while-do(
  $input,
  fn($result) { abs($result * $result - $input) >= 0.0000000001 },
  fn($guess) { ($guess + $input div $guess) div 2 }
) => round(5)
Result: 1984. Computes the square root of a number.

fn:do-until

Added: New 4.0 function, replacing hof:until.

Signature
fn:do-until(
  $input      as item()*,
  $action     as fn(item()*, xs:integer) as item()*,
  $predicate  as fn(item()*, xs:integer) as xs:boolean
) as item()*
SummaryThis function provides a way to write functionally clean and interruptible iterations, commonly known as do while/until loops:
  1. $action is called with $input and the result is adopted as new $input.
  2. $predicate is called with $input. If the result is false, step 1 is repeated.
  3. Otherwise, $input is returned.
Examples
do-until(
  (),
  fn($value, $pos) { $value, $pos * $pos },
  fn($value) { foot($value) > 50  }
)
Result: 1, 4, 9, 16, 25, 36, 49, 64. The loop is interrupted once the last value of the generated sequence is greater than 50.
do-until(
  (1, 0),
  fn($value) { $value[1] + $value[2], $value },
  fn($value) { avg($value) > 10 }
)
Result: 55, 34, 21, 13, 8, 5, 3, 2, 1, 1, 0. The computation is continued as long as the average of the first Fibonacci numbers is smaller than 10.

fn:identity

Added: New 4.0 function, replacing hof:id.

Signature
fn:identity(
  $input  as item()*
) as item()*
SummaryReturns $input unchanged. This function isn’t useful on its own, but can be used as an argument to other higher-order functions.
Examples
let $sort := sort(?, (), identity#1)
let $reverse-sort := sort(?, (), fn($x) { -$x })
return string-join((
  $sort((1, 5, 3, 2, 4)),
  '|',
  $reverse-sort((1, 5, 3, 2, 4))
))
Result: '12345|54321'
map:for-each({ 1: 'one', 2: 'two' }, identity#1)
Result: 1, 2. map:for-each invokes the supplied function with the key and value of every entry of the supplied map. As identity#1 takes only the first argument (the second argument is ignored, see calling higher-order functions) the result is the sequence of keys of the map.

fn:apply

Signature
fn:apply(
  $function   as fn(*),
  $arguments  as array(*)
) as item()*
SummaryThe supplied $function is invoked with the specified $arguments. The arity of the function must be the same as the size of the array.
Examples
apply(concat#5, array { 1 to 5 })
Result: '12345'
apply(fn($a) { sum($a) }, [ 1 to 5 ])
Result: 15
apply(count#1, [ 1, 2 ])
Raises an error as the array has two members.

fn:op

Added: New 4.0 function.

Signature
fn:op(
  $operator  as xs:string
) as fn(item()*, item()*) as item()*
SummaryReturns a new function that applies the specified $operator to two arguments. The supported operators are:
+ * - | || < <= = >= > != << >> is mod div idiv and or lt le eq ge gt ne to union intersect except otherwise
Examples
for-each-pair(1 to 3, 4  to 6, op('+'))
Result: 5, 7, 9
map:keys-where(
  { 2: 1234, 3: 3, 4: 5678, 5: 5 },
  op('=')
)
Result: 3, 5

Folds

A fold, also called reduce or accumulate in other languages, is a very basic higher-order function on sequences. It starts from a seed value and incrementally builds up a result, consuming one element from the sequence at a time and combining it with the aggregate of a user-defined function.

Folds are one solution to the problem of not having state in functional programs. Solving a problem in imperative programming languages often means repeatedly updating the value of variables, which isn’t allowed in functional languages.

Calculating the product of a sequence of integers for example is easy in Java:

public int product(int[] seq) {
  int result = 1;
  for(int i : seq) {
    result = result * i;
  }
  return result;
}

Nice and efficient implementations using folds will be given below.

The linear folds on sequences come in two flavors. They differ in the direction in which they traverse the sequence:

fn:fold-left

Updated: Positional argument added to the function parameter. Calculations are skipped once a condition in the supplied function is met.

Signature
fn:fold-left(
  $input   as item()*,
  $zero    as item()*,
  $action  as fn(item()*, item(), xs:integer) as item()*
) as item()*
SummaryThe left fold traverses the $input from the left. The query fold-left(1 to 5, 0, $f), for example, would be evaluated as:
$f($f($f($f($f(0, 1), 2), 3), 4), 5)

An equivalent XQuery function is:

declare function fold-left(
  $input   as item()*,
  $zero    as item()*,
  $action  as fn(item()*, item()) as item()*
) as item()* {
  if (empty($input)) then $zero
  else fold-left(
    tail($input),
    $action($zero, head($input)),
    $action
  )
};
Examples
fold-left(1 to 5, 1, fn($result, $curr) { $result * $curr })
Result: 120. Computes the product of a sequence of integers.
fold-left(1 to 5, '$seed',
  concat('$f(', ?, ', ', ?, ')')
)
Illustrates the evaluation order and returns $f($f($f($f($f($seed, 1), 2), 3), 4), 5).
let $from-digits := fold-left(?, 0,
  fn($n, $d) { 10 * $n + $d }
)
return (
  $from-digits(1 to 5),
  $from-digits((4, 2))
)
Result: 12345, 42. Builds a decimal number from digits.
fold-left(
  1 to 10000000000,
  1,
  fn($n, $curr) { if($n > 100000) then $n else $n * $curr }
)
Result: 362880. Once the condition is met, further calculations are skipped.

fn:fold-right

Updated: Positional argument added to the function parameter. Calculations are skipped once a condition in the supplied function is met.

Signature
fn:fold-right(
  $input   as item()*,
  $zero    as item()*,
  $action  as fn(item(), item()*, xs:integer) as item()*
) as item()*
SummaryThe right fold traverses the $input from the right. The query fold-right(1 to 5, 0, $f), for example, would be evaluated as:
$f(1, $f(2, $f(3, $f(4, $f(5, 0)))))

Note that the order of the arguments of $fun are inverted compared to that in fn:fold-left:

declare function fold-right(
  $input   as item()*,
  $zero    as item()*,
  $action  as fn(item(), item()*) as item()*
) as item()* {
  if (empty($input)) then $zero
  else $action(
    head($input),
    fold-right(tail($input), $zero, $action)
  )
};
Examples
fold-right(1 to 5, 1,
  fn($curr, $result) { $result * $curr }
)
Result: 120. Computes the product of a sequence of integers.
fold-right(1 to 5, '$seed',
  concat('$f(', ?, ', ', ?, ')')
)
Illustrates the evaluation order and $f(1, $f(2, $f(3, $f(4, $f(5, $seed))))).
let $reverse := fold-right(?, (), fn($item, $rev) { $rev, $item })
return $reverse(1 to 5)
Result: 5, 4, 3, 2, 1. Reverses a sequence of items.

Diagnostics

fn:message

Added: New 4.0 function, replacing prof:dump.

Signature
fn:message(
  $input  as item()*,
  $label  as xs:string?  := ()
) as empty-sequence()
SummaryGenerates a serialized representation of $input, optionally prefixed with $label, and sends it to STDERR, the Info View of the Graphical User Interface or to the the log files in the server context. The function itself returns an empty sequence. In contrast to fn:trace, the evaluated result will be swallowed.
Examples
'Hello' => trace() => void()
Results can also be output and swallowed with fn:trace and fn:void.

fn:trace

Signature
fn:trace(
  $input  as item()*,
  $label  as xs:string?  := ()
) as item()*
SummaryGenerates a serialized representation of $input, optionally prefixed with $label, and sends it to STDERR, the Info View of the Graphical User Interface or to the the log files in the server context. In contrast to fn:message, the evaluated result is returned unchanged.

Miscellaneous

fn:hash

Added: New 4.0 function, replacing the custom hashing functions.

Signature
fn:hash(
  $value    as (xs:string|xs:hexBinary|xs:base64Binary)?  := (),
  $options  as map(*)?                                    := {}
) as xs:hexBinary?
SummaryComputes a hash for the given $value. The following $options are available:
optiondefaultdescription
algorithmMD5The hash algorithm. Supported values are MD5, SHA-1, SHA-256, and the cyclic redundancy check CRC-32.
Examples
string(hash(''))
Result: 'D41D8CD98F00B204E9800998ECF8427E'
string(hash('', { 'algorithm': 'SHA-1' }))
Result: 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'
hash('', { 'algorithm': 'CRC-32' }) => string()
Result: '00000000'
hash('BaseX', { 'algorithm': 'CRC-32' }) => string()
Result: '4C06FC7F'

fn:seconds

Added: New 4.0 function.

Signature
fn:seconds(
  $value  as xs:decimal?  := ()
) as xs:dayTimeDuration?
SummaryReturns a duration for $value, which specified the number of seconds.
Examples
seconds(0)
Result: xs:dayTimeDuration('PT0S')
seconds(86_400.1)
Result: xs:dayTimeDuration('P1DT0.1S')
current-time() + seconds(100)
Adds 100 seconds to the current time.

fn:default-language

Returns the default language used for formatting numbers and dates. BaseX always returns en.

Changelog

Version 11.0

⚡Generated with XQuery