Main Page » XQuery » Functions » Standard Functions

Standard Functions

This page presents selected functions of the XQuery 3.1 and XQuery 4.0 standards 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 in the http://www.w3.org/2005/xpath-functions namespace, to which the fn prefix is statically bound.

Strings

fn:char

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:string-join

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:pad-string

Added: New function.

Signature
fn:pad-string(
  $value    as xs:anyAtomicType?,
  $length   as xs:integer,
  $options  as map(*)?  := {}
) as xs:string
SummaryCreates a string by extending $value to the requested $length with padding characters. As in fn:string-join, the supplied value is atomized and cast to a string. A value that is already long enough is returned unchanged: the function never truncates. The following $options are available:
  • padding: string to pad with (default: ' '). It is repeated as often as required and cut to fit; it must not be empty.
  • side: side on which the padding is added: end (default), start or both. With both, an odd padding character is appended at the end.
Examples
pad-string('abc', 6)
Result: 'abc '
pad-string('abc', 6, { 'side': 'start' })
Result: ' abc'
pad-string(42, 6, { 'padding': '0', 'side': 'start' })
Result: '000042'
pad-string('Chapter 1', 20, { 'padding': '.' })
Result: 'Chapter 1...........'. Dot leaders in a table of contents.
pad-string('abcdef', 3)
Result: 'abcdef'. Padding never truncates.

fn:graphemes

Added: New function.

Signature
fn:graphemes(
  $value  as xs:string?
) as xs:string*
SummarySplits $value into a sequence of strings, each containing a single extended grapheme cluster as defined by UAX #29. Returns an empty sequence if $value is empty or the empty sequence.
Examples
graphemes("a" || char(0x308) || "b")
Result: "a" || char(0x308), "b". I.e., a + ◌̈ + b, three characters, two graphemes.
graphemes(char(0x1F476) || char(0x200D) || char(0x1F6D1))
Result: char(0x1F476) || char(0x200D) || char(0x1F6D1). I.e., 👶 + ZWJ + 🛑: three characters, one grapheme.
graphemes(char('\r') || char('\n'))
Result: char('\r') || char('\n'). I.e., CR + LF: two characters, one grapheme.

fn:collation

Signature
fn:collation(
  $options  as map(*)
) as xs:string
SummaryGenerates a collation URI with the specified $options. Depending on the availability of ICU, the returned collation will either use the standard or the ICU collation features (see Collations for more details).
Examples
collation({ 'language': 'de' })
Result: "http://basex.org/collation?language=de". Returned without ICU.
collation({ 'language': 'de' })
Result: "http://www.w3.org/2013/collation/UCA?language=de". Returned with ICU embedded.

fn:collation-available

Signature
fn:collation-available(
  $collation  as xs:string
) as xs:boolean
SummaryChecks if the specified $collation is supported.

fn:collation-key

Signature
fn:collation-key(
  $value      as xs:string,
  $collation  as xs:string?  := fn:default-collation()
) as xs:base64Binary
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") ]

Regular Expressions

fn:replace

Signature
fn:replace(
  $value        as xs:string?,
  $pattern      as xs:string,
  $replacement  as (xs:string|fn($s as item(), $g as item()*) as item()?)?  := (),
  $flags        as xs:string?  := ''
) as xs:string
SummarySearches the regular expression $pattern in $value and performs a $replacement, using optional $flags. The replacement argument can either be a string, or a function that will be invoked with the currently matched string ($s) and the currently captured groups ($g).
Examples
replace('a1c', '\d', 'X')
Result: 'aXc'
replace('1aBc2', '[a-z]', 'X', 'i')
Result: '1XXX2'
replace('1aBc2', '[a-z]', upper-case#1)
Result: '1ABC2'
replace("Chapter 9", "[0-9]+", fn($match) { $match + 1 })
Result: 'Chapter 10'
replace(
  "12°34′57″",
  "([0-9]+)°([0-9]+)′([0-9]+)″",
  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

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:matching-segments

Added: New function.

Signature
fn:matching-segments(
  $value    as xs:string?,
  $pattern  as xs:string,
  $flags    as xs:string?  := ''
) as fn:matching-segment-record*
SummaryApplies the regular expression $pattern to $value, using optional $flags, and returns one record for each match. Each record contains the matched substring, its 1-based position within the input, and a map of all captured groups. A group is keyed by its group number, or, if it is a named capturing group ((?<name>…)), by its name.
Examples
matching-segments("The cat sat on the mat.", "\w+")?substring
Result: 'The', 'cat', 'sat', 'on', 'the', 'mat'
matching-segments(
  "08-12-03",
  "^(\d+)\-(\d+)\-(\d+)$")?groups ! (?1?group, ?2?group, ?3?group
)
Result: '08', '12', '03'
matching-segments("Chapter 5", "(Chapter|Appendix)(?=\s+([0-9]+))")?groups?2
Result: { "group": "5", "position": 9 }. Groups captured inside a lookahead are included in the result.
matching-segments(
  "2026-06-25",
  "(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})"
)?groups?year?group
Result: '2026'. A named capturing group is keyed by its name instead of its group number.

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 fn:random-number-generator-record
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)

fn:round

Signature
fn:round(
  $value      as xs:numeric?,
  $precision  as xs:integer?  := 0,
  $mode       as xs:string?  := 'half-to-ceiling'
) as xs:numeric?
SummaryRounds a $value to a specified number of decimal places, using the specified $precision and $mode.
Allowed values for $mode are: floor, ceiling, toward-zero, away-from-zero, half-to-floor, half-to-ceiling, half-toward-zero, half-away-from-zero, and half-to-even.
Examples
round(1.5)
Result: 2.0
round(15, -1)
Result: 20
round(9.9999, 1, 'floor')
Result: 9.9

fn:divide-decimals

Signature
fn:divide-decimals(
  $value      as xs:decimal,
  $divisor    as xs:decimal,
  $precision  as xs:integer?  := 0
) as record(quotient as xs:decimal, remainder as xs:decimal)
SummaryThe function returns the quotient and remainder of a decimal division for the specified $value, the $divisor and an optional $precision.
Examples
divide-decimals(10, 3)
Result: { "quotient": 3, "remainder": 1 }
divide-decimals(10, 7, 3)
Result: { "quotient": 1.428, "remainder": 0.004 }

Nodes

fn:transitive-closure

Signature
fn:transitive-closure(
  $node  as gnode()?,
  $step  as fn($current as gnode()) as gnode()*
) as gnode()*
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 gnode()*
) as gnode()*
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

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"
}

fn:siblings

Signature
fn:siblings(
  $node  as gnode()?  := .
) as gnode()*
SummaryReturns the siblings of a $node, including the node itself.
Examples
siblings(<xml><a/><b/><c/></xml>/b)
Result: <a/>, <b/>, <c/>

fn:path

Signature
fn:path(
  $node     as gnode()?  := .,
  $options  as map(*)?  := {}
) as xs:string?
SummaryReturns a string that can be used as path expression to select the supplied $node, using the specified $options:
optiondefaultdescription
origin()If present, the returned path will be relative to this origin node.
lexicalfalse()If enabled, fn:name() will be used to serialize node names.
namespaces{}A map with prefixes and namespace URIs. If a prefix is used for a namespace, it is used instead of the Q{URI} syntax when serializing nodes names.
indexestrue()By default, the index positions of nodes are included in the string.
Examples
let $xml := document { <xml><a/></xml> }
return path($xml/xml/a, { 'indexes': false() })
Result: '/Q{}xml/Q{}a'
let $xml := document {
  <xml xmlns='URI'><a/></xml>
}
let $namespaces := in-scope-namespaces($xml/*)
return path($xml/*:xml/*:a, { 'namespaces': $namespaces })
Result: '/xml[1]/a[1]'

JNodes

JNodes wrap maps and arrays in a tree structure with identity and document order, enabling XPath path expressions to navigate JSON-like data. See JNodes for an introduction.

fn:jtree

Added: New function.

Signature
fn:jtree(
  $input  as (map(*)|array(*))
) as jnode((), (map(*)|array(*)))
SummaryCreates a root JNode that wraps the supplied map or array $input, enabling path expressions to navigate the resulting JTree.

Calling jtree($X) is equivalent to the path expression $X/.: maps and arrays that appear as the left-hand operand of / are wrapped implicitly, so an explicit call is rarely needed.

Examples
jtree([ "a", "b", "c" ])/*[1]
Result: "a"
jtree([ "a", "b" ])/* =!> jkey()
Result: 1, 2

fn:jkey

Added: New function.

Signature
fn:jkey(
  $input  as jnode()?  := .
) as xs:anyAtomicType?
SummaryReturns the jkey property of $input: the map key or 1-based array index that identifies this JNode within its parent. Returns an empty sequence if $input is empty or is a root JNode.
Examples
let $array := [ 1, 4.5, "eight", 10 ]
return $array/jnode(*, xs:integer) =!> jkey()
Result: 1, 4. Positions of the integer members.
let $map := { 'Mo': 'Monday', 'Tu': 'Tuesday', 'We': 'Wednesday' }
return $map/(Mo|We|Fr|Su) =!> jkey()
Result: "Mo", "We". Keys that actually exist in the map; Fr and Su are silently ignored.
let $array := [ [ 4, 18 ], [ 30, 4, 22 ] ]
return $array/descendant::*[. > 25]/ancestor-or-self::* =!> jkey()
Result: 2, 1. The subarray [ 30, 4, 22 ] is at index 2; the value 30 is at index 1 within it.

fn:jvalue

Added: New function.

Signature
fn:jvalue(
  $input  as jnode()?  := .
) as item()*
SummaryReturns the jvalue property of $input: the value wrapped by the JNode. Returns an empty sequence if $input is empty. In most contexts an explicit call is unnecessary, because the coercion rules automatically extract the value when a JNode is used where an atomic value, map, or array is required. Notable exceptions are effective boolean value tests (if ($jnode) tests for the existence of a child, not its truth value) and calls to functions that accept arbitrary sequences such as count or deep-equal.
Examples
let $array := [ 1, 3, 4.5, 7, "eight", 10 ]
return $array/jnode(*, xs:integer) =!> jvalue()
Result: 1, 3, 7, 10
let $map := { 'Mo': 'Monday', 'Tu': 'Tuesday', 'We': 'Wednesday' }
return $map/(Mo|We|Fr|Su) =!> jvalue()
Result: "Monday", "Wednesday"

fn:jposition

Added: New function.

Signature
fn:jposition(
  $input  as jnode()?  := .
) as xs:integer?
SummaryReturns the jposition property of $input: the 1-based position of the map or array that produced this JNode within the sequence that is the parent entry or member value. Returns an empty sequence if $input is empty or is a root JNode. This property is always 1 for JTrees derived from JSON, since JSON values are never multi-item sequences. It is only relevant when a map entry or array member holds a sequence containing multiple maps or arrays.
Examples
let $input := {
  "a": [ 10, 20 ],
  "b": ([ 30, 40 ], [], 0, [ 50 ])
}
return $input/b/* ! [ jposition(), jkey(), jvalue() ]
The result:
[ 1, 1, 30 ]
[ 1, 2, 40 ]
[ 4, 1, 50 ]

Dates and Times

fn:build-dateTime

Added: New function.

Signature
fn:build-dateTime(
  $value  as fn:dateTime-record
) as xs:anyAtomicType?
SummaryConstructs a Gregorian value from the components of the $value record.
Examples
build-dateTime({
  "year": 2026,
  "month": 4,
  "day": 8,
  "hours": 18,
  "minutes": 46,
  "seconds": 12,
  "timezone": xs:dayTimeDuration("PT2H")
})
Result: xs:dateTime("2026-04-08T18:46:12+02:00")

fn:civil-timezone

Signature
fn:civil-timezone(
  $value  as xs:dateTime,
  $place  as xs:string?  := ()
) as xs:dayTimeDuration
SummaryReturns the timezone offset for a given date/time $value and $place. If no place is specified, the system’s default place is used.
Examples
civil-timezone(xs:dateTime('2001-01-01T11:11:11Z'))
Result: xs:dayTimeDuration('PT1H'). Returned when being executed in Germany.
civil-timezone(xs:dateTime('2001-07-01T11:11:11Z'))
Result: xs:dayTimeDuration('PT2H'). Returned when being executed in Germany.
let $dt := xs:dateTime('2024-07-01T01:01:01Z')
return adjust-dateTime-to-timezone($dt, civil-timezone($dt))
Result: xs:dateTime('2024-07-01T03:01:01+02:00'). Returned when being executed in Germany.
civil-timezone(xs:dateTime('2024-12-24T12:24:48'), 'Africa/Abidjan')
Result: xs:dayTimeDuration('PT0S')

fn:parts-of-dateTime

Signature
fn:parts-of-dateTime(
  $value  as xs:anyAtomicType?
) as fn:dateTime-record?
SummaryReturns the components of a Gregorian value.
Examples
parts-of-dateTime(xs:dateTime('2026-04-08T18:46:12+02:00'))
Result: { "year": 2026, "month": 4, "day": 8, "hours": 18, "minutes": 46, "seconds": 12, "timezone": "PT2H"}

fn:unix-dateTime

Signature
fn:unix-dateTime(
  $value  as xs:nonNegativeInteger?  := 0
) as xs:dateTimeStamp
SummaryConverts a Unix timestamp to an xs:dateTimeStamp.
Examples
unix-dateTime(0)
Result: xs:dateTime('1970-01-01T00:00:00Z')

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

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.

fn:parse-uri

Signature
fn:parse-uri(
  $value    as xs:string?,
  $options  as map(*)?  := {}
) as fn:uri-structure-record?
Summary Parses the supplied URI string and returns a map with its constituent components.

For a full description of behavior and the $options, see fn:parse-uri.

Examples
parse-uri("https://basex.org/download/")
The result:
{
  "uri": "https://basex.org/download/",
  "scheme": "https",
  "hierarchical": true(),
  "authority": "basex.org",
  "host": "basex.org",
  "path": "/download/",
  "path-segments": ("", "download", ""),
  "absolute": true()
}

fn:build-uri

Added: New function.

Signature
fn:build-uri(
  $parts    as fn:uri-structure-record,
  $options  as map(*)  := {}
) as xs:string
Summary Constructs a URI from the $parts provided.

For a full description of behavior and the $options, see fn:build-uri.

Examples
build-uri({
  "scheme": "https",
  "host": "docs.basex.org",
  "path": "/main"
})
Result: 'https://docs.basex.org/main'

Comparisons

fn:atomic-equal

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: Diagnostics via the debug option.

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 an options map:
optiondefaultdescription
base-urifalse()Consider base-uri of nodes.
collationdefault-collation()Collation to be used.
commentsfalse()Consider comments.
debugfalse()If the result is false(), output the items that were found to be different (see Debugging).
id-propertyfalse()Consider id property of elements and attributes.
idrefs-propertyfalse()Consider idrefs property of elements and attributes.
ignore-empty-entriesfalse()Ignore map entries and array members whose value is an empty sequence.
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.
map-orderfalse()Consider the order of map entries.
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.

As BaseX is not schema-aware, all nodes have the same type annotations, and typed values are equal to string values. The options typed-values, type-annotations and type-variety are accepted and ignored.

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

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

Signature
fn:starts-with-subsequence(
  $input        as item()*,
  $subsequence  as item()*,
  $compare      as (fn($a, $b) 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

Signature
fn:ends-with-subsequence(
  $input        as item()*,
  $subsequence  as item()*,
  $compare      as (fn($a as item(), $b as 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

Signature
fn:contains-subsequence(
  $input        as item()*,
  $subsequence  as item()*,
  $compare      as (fn($a as item(), $b as 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

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

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

Signature
fn:every(
  $input      as item()*,
  $predicate  as (fn($item, $pos) 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

Signature
fn:some(
  $input      as item()*,
  $predicate  as (fn($item, $pos) 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()
some(1 to 5, fn { . > 3 })
Result: true()
some(())
Result: false()

fn:index-where

Signature
fn:index-where(
  $input      as item()*,
  $predicate  as fn($item as item(), $pos as 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

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

fn:sort-by

Signature
fn:sort-by(
  $input  as item()*,
  $keys   as map(*)*
) as item()*
SummaryReturns a new sequence with sorted $input items, matching the order of the sort $keys.
optiondefaultdescription
keyfn:data#1Sort function.
collationCollation URI.
order'ascending'Order (ascending, descending)
Examples
sort-by((-2, 1, 3), { 'key': abs#1 })
Result: 1, -2, 3
sort-by(1 to 3, { 'order': 'descending' })
Result: 3, 2, 1

fn:sort-with

Signature
fn:sort-with(
  $input        as item()*,
  $comparators  as (fn($a as item(), $b as 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

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

fn:trunk

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

fn:items-at

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

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 smaller than start, the items are returned in reverse order.
  • If a negative start or end is specified, the counter starts 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

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

Signature
fn:subsequence-where(
  $input  as item()*,
  $from   as (fn($item as item(), $pos as xs:integer) as xs:boolean)?  := true#0,
  $to     as (fn($item as item(), $pos as 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

Signature
fn:take-while(
  $input      as item()*,
  $predicate  as fn($item as item(), $pos as 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:insert-separator

Updated: Renamed (before: fn:sequence-join).

Signature
fn:insert-separator(
  $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)
=> insert-separator('|')
=> string-join()
Result: '1|2|3'
insert-separator((<_>1</_>, <_>2</_>, <_>3</_>), '; ')
Inserts semicolon strings between the three input items.

fn: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

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 but the resulting value is not required.
Examples
void(fetch:binary('http://my.rest.service'))
Performs an HTTP request and ignores the result.

Aggregations

fn:highest

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

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

Signature
fn:duplicate-values(
  $values     as xs:anyAtomicType*,
  $collation  as xs:string?  := fn:default-collation()
) as xs:anyAtomicType*
SummaryReturns all values that appear for the second time in $values. If no $collation is specified, the function is similar 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

Signature
fn:partition(
  $input       as item()*,
  $split-when  as fn($group, $next, $pos) 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:doc

Added: trusted option.

Removed: entity-expansion-limit and allow-external-entities options.

Signature
fn:doc(
  $source   as xs:string?,
  $options  as map(*)?  := {}
) as document-node()?
Summary

Retrieves and parses an XML document from a given URI and returns a document-node() item.

Within $options, the following keys can be specified:

optiondefaultdescription
dtd-validationfalse()Enables DTD validation if set to true().
stabletrue()Ensures deterministic results when set to true().
strip-spacefalse()Controls whether whitespace-only text nodes are stripped.
xincludefalse()Expands xi:include elements if set to true(). Requires the trusted option to be enabled.
xsd-validationskipSpecifies XSD validation mode: strict, lax, or skip.
use-xsi-schema-locationfalse()Determines whether xsi:schemaLocation and xsi:noNamespaceSchemaLocation declarations are followed. Requires the trusted option to be enabled.

Additionally, these BaseX XML Parsing options are supported, using lower-case option names:

optiondefaultdescription
dtdtrue()When set to true(), external entities are processed, otherwise they are ignored.
intparsefalse()Uses the internal XML parser instead of the standard Java XML parser.
stripnsfalse()Strips all namespaces from an XML document while parsing.
trustedfalse()Allows the parser to fetch external resources (external DTDs and entities, XInclude documents, and referenced schemas). The default is controlled by the FNXMLTRUSTED option.
Examples
doc('example.xml')
The result:
<root>
   <a> </a>
</root>

doc('example.xml', { 'strip-space': true() })
Result: <root><a/></root>
doc('book.xml', { 'xinclude': true(), 'trusted': true() })
Parses book.xml and expands its xi:include elements. Because XInclude fetches external documents, the trusted option must be enabled; without it, the call is rejected with err:FODC0016 (External resources not available, call is untrusted).

fn:doc-available

Added: trusted option.

Signature
fn:doc-available(
  $source   as xs:string?,
  $options  as map(*)?  := {}
) as xs:boolean
Summary

Checks if an XML document can be retrieved and parsed from a given URI. Returns true if fn:doc($source, $options) would return a document node, and false otherwise.

The recognized options are the same as for fn:doc.

Examples
doc-available('https://example.org/example.xml')
Result: false()

fn:unparsed-binary

Signature
fn:unparsed-binary(
  $source  as xs:string?
) as xs:base64Binary?
SummaryRetrieves $source and returns it as a binary.
Examples
unparsed-binary('https://files.basex.org/releases/BaseX.jar')
Retrieves the latest release of BaseX.

fn:parse-integer

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

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 an 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:parse-xml

Added: trusted option.

Removed: entity-expansion-limit and allow-external-entities options.

Signature
fn:parse-xml(
  $value    as (xs:string | xs:hexBinary | xs:base64Binary)?,
  $options  as map(*)?  := ()
) as document-node(*)?
Summary

Parses a string as XML and returns a document-node() item.

If the $value is supplied as a binary (e.g., xs:base64Binary or xs:hexBinary), its encoding may be inferred from a byte order mark or an XML declaration. The input is then processed like a resource retrieved via fn:doc.

The recognized $options are the same as for fn:doc, with the following differences: the stable option does not apply; a base-uri can be supplied (defaulting to the static base URI of the function call); and xsd-validation does not support the values lax and type.

Examples
parse-xml('<Greeting>Hello, world!</Greeting>')
Result: <Greeting>Hello, world!</Greeting>

fn:parse-xml-fragment

Signature
fn:parse-xml-fragment(
  $value    as (xs:string | xs:hexBinary | xs:base64Binary)?,
  $options  as map(*)?  := ()
) as document-node()?
Summary

This function takes an XML fragment as a string or binary input and returns it as a document node.

If the $value is supplied as binary, its encoding is inferred as with fn:unparsed-text, and it is parsed as an external general parsed entity.

Within $options, the standard options are supported:

optiondefaultdescription
base-uribase-uri of document. Defaults to the static base URI of the function call.
strip-spacefalse()Determines whether whitespace-only text nodes are removed from the resulting document.

Additionally, this BaseX XML Parsing option is supported, using a lower-case option name:

optiondefaultdescription
stripnsfalse()Strips all namespaces from an XML document while parsing.
Examples
parse-xml-fragment('<a/> <b/> <c/>')/node()
Result: (<a/>, text {' '}, <b/>, text {' '}, <c/>)

fn:xsd-validator

Added: New function.

Signature
fn:xsd-validator(
  $options  as map(*)?  := {}
) as fn(node()?) as record(is-valid as xs:boolean, typed-node as node()?, error-details as map(*)*)
Summary

Assembles an XSD schema and returns a function that validates a document or element node against this schema. The returned function returns an empty sequence if the supplied node is empty. Otherwise, it returns a record with the field is-valid and, on demand, the validated node (typed-node) and details on the invalidities that were found (error-details).

The following $options are available:

optiondefaultdescription
schema()Schema documents, supplied as element(xs:schema)* nodes.
schema-location()URIs of schema documents. Relative URIs are resolved against the static base URI of the function call.
use-xsi-schema-locationfalse()Retrieve schema documents that are referenced by xsi:schemaLocation and xsi:noNamespaceSchemaLocation attributes of the validated node.
trustedAllow access to schema documents that are indirectly referenced (e.g., via xs:include). The default is controlled by the FNXMLTRUSTED option.
xsd-versionRequested XSD version. An error is raised if no processor with this version is available (see Validation Functions).
return-typed-nodetrue()Include the validated node in the result.
return-error-detailsfalse()Include details on invalidities in the result. If the option is disabled, validation stops after the first error.

As BaseX is not schema-aware, the returned node has no type annotations, and the options validation-mode (with the values lax and by-type), type and target-namespace are rejected with an error.

Examples
let $schema := <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
  <xs:element name='distance' type='xs:decimal'/>
</xs:schema>
let $validator := xsd-validator({ 'schema': $schema })
return (
  $validator(<distance>8.5</distance>)?is-valid,
  $validator(<distance>8.5km</distance>)?is-valid
)
Result: (true(), false())

fn:invisible-xml

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

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

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

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'

CSV

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

fn:csv-to-arrays

Signature
fn:csv-to-arrays(
  $value    as xs:string?,
  $options  as map(*)?  := {}
) as array(xs:string)*
SummaryParses the supplied $value as CSV data and returns an item representation, using the supplied $options. The result is returned as a sequence of arrays of strings. For details, and for the allowable options, see fn:csv-to-arrays.

With our custom csv:parse function, additional conversion formats are available.

Examples
csv-to-arrays(
  string-join(('Name,City', 'Rossi,Rome', 'Da Silva,Rio de Janeiro'), char('\n'))
)
Result: [ "Name", "City" ], [ "Rossi", "Rome" ], [ "Da Silva", "Rio de Janeiro" ]
csv-to-arrays(
  string-join(('Product;Price', 'Laptop;1200', 'Mouse;25'), char('\n')),
  { 'separator': ';' }
)
Result: [ "Product", "Price" ], [ "Laptop" , "1200" ], [ "Mouse", "25" ]

fn:parse-csv

Signature
fn:parse-csv(
  $value    as xs:string?,
  $options  as map(*)?  := {}
) as fn:parsed-csv-structure-record?
SummaryParses the supplied $value as CSV data and returns an item representation, using the supplied $options. The result is returned as a map with these keys:
  • columns is a sequence of strings containing column names, if any
  • column-index is a map from column names to (one-based) column positions
  • rows is a sequence of arrays of strings representing the parsed rows of the CSV data
  • get is a function that returns a field in the result that is identified by row and column. Its signature is function(xs:positiveInteger, (xs:positiveInteger | xs:string)) as xs:string? where the first argument is the (one-based) row number, and the second argument is the (one-based) column number or the column name.

For more details, and for the allowable options, see fn:parse-csv.

With our custom csv:parse function, additional conversion formats are available.

Examples
parse-csv(
  string-join(('Name,City', 'Rossi,Rome', 'Da Silva,Rio de Janeiro'), char('\n')),
  { 'header': true() }
)
The result:
{
  "columns": ("Name", "City"),
  "column-index": { "Name": 1, "City": 2},
  "rows": ([ "Rossi", "Rome" ], [ "Da Silva", "Rio de Janeiro" ]),
  "get": (anonymous-function)#2
}

parse-csv(
  string-join(('Laptop;1200', 'Mouse;25', 'Keyboard;45'), char('\n')),
  { 'separator': ';', 'header': ('Product', 'Price') }
)
The result:
{
  "columns": ("Product", "Price"),
  "column-index": { "Product": 1, "Price": 2},
  "rows": ([ "Laptop", "1200" ], [ "Mouse", "25" ], [ "Keyboard", "45" ]),
  "get": (anonymous-function)#2
}

fn:csv-doc

Signature
fn:csv-doc(
  $source   as xs:string?,
  $options  as map(*)?  := {}
) as fn:parsed-csv-structure-record?
Summary Reads an external resource containing CSV data, and returns the results as a record structure with information about column names and row data, using the supplied $options.

The result is equivalent to reading the CSV file as binary using unparsed-binary and parsing the content with parse-csv. If the $source is the empty sequence, the function returns the empty sequence.

For more details and allowable options, see fn:csv-doc.

With our custom csv:doc function, additional conversion formats are available.

Examples
csv-doc('input.csv', { 'header': true() })
The result:
{
  "columns": ("Name", "Age"),
  "column-index": { "Name": 1, "Age": 2 },
  "rows": ([ "Alice", "30" ], [ "Bob", "25" ]),
  "get": (anonymous-function)#2
}

fn:csv-to-xml

Signature
fn:csv-to-xml(
  $value    as xs:string?,
  $options  as map(*)?  := {}
) as document-node(fn:csv)?
SummaryParses the supplied $value as CSV data and returns an item representation, using the supplied $options. The result is returned as a document node with a csv root element in the http://www.w3.org/2005/xpath-functions namespace. It has these child elements, which are all in the same namespace:
  • columns holds the column names in a sequence of column elements (only present if there are column names)
  • rows holds a sequence of row elements representing the rows of the CSV data. Each row has field elements with the field values. Their column attribute indicates the column name, if any
For more details, and for the allowable options, see fn:csv-to-xml.

With our custom csv:parse function, additional conversion formats are available.

Examples
csv-to-xml(
  string-join(('Laptop;1200', 'Mouse;25', 'Keyboard;45'), char('\n')),
  { 'separator': ';', 'header': ('Product', 'Price') }
)
The result:
<csv xmlns="http://www.w3.org/2005/xpath-functions">
  <columns>
    <column>Product</column>
    <column>Price</column>
  </columns>
  <rows>
    <row>
      <field column="Product">Laptop</field>
      <field column="Price">1200</field>
    </row>
    <row>
      <field column="Product">Mouse</field>
      <field column="Price">25</field>
    </row>
    <row>
      <field column="Product">Keyboard</field>
      <field column="Price">45</field>
    </row>
  </rows>
</csv>

HTML

Strings and binary data can be parsed as HTML to XDM items.

fn:parse-html

Signature
fn:parse-html(
  $value    as (xs:string | xs:hexBinary | xs:base64Binary)?,
  $options  as map(*)?  := {}
) as document-node(*:html)?
SummaryParses the supplied $value as HTML and returns an item representation, using the supplied $options. The result is returned as a document node with a *:html root element. In contrast to other HTML parsing in BaseX, this function by default uses the Validator.nu HTML Parser, but it can be instructed to use TagSoup by supplying option method=tagsoup. See HTML Parser for more information about the available HTML parsers and their options.

With our custom html:parse function, additional conversion formats are available.

Examples
parse-html(
  '<!DOCTYPE html>' ||
  '<html><head><meta charset="UTF-8"></head><body>Hello, World!</body></html>'
)
The result:
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta charset="UTF-8"/>
  </head>
  <body>Hello, World!</body>
</html>

fn:html-doc

Signature
fn:html-doc(
  $source   as xs:string?,
  $options  as map(*)?  := {}
) as document-node(*:html)?
SummaryReads an external resource containing HTML data, retrieved from the $source location, and returns the result of parsing the resource as HTML, using the supplied $options.

The returned result is a document node whose root element is <html>, conforming to the HTML structure parsed from the input. The result is equivalent to reading the file as binary with unparsed-binary and parsing it via parse-html.

For more details and allowable options, see fn:html-doc.

With our custom html:doc function, additional parsing features are available.

Examples
html-doc('https://basex.org/download')//@href[contains(., '.zip')]!string()
Returns the download link for the latest BaseX version.

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 JSON 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.

With our custom json:parse function, additional conversion formats are available.

Examples
parse-json('{ "name": "john" }')
Result: { "name": "john" }
parse-json('[ 1, 2, 4, 8, 16 ]')
Result: [ 1, 2, 4, 8, 16 ]

fn:json-doc

Signature
fn:json-doc(
  $source   as xs:string?,
  $options  as map(*)?  := {}
) as item()?
SummaryParses the JSON string retrieved from the $source location and returns an item representation, using the supplied $options.

With our custom json:doc function, additional conversion formats are available.

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(fn:*)?
SummaryParses the supplied $value as a JSON string and returns an XML representation, using the supplied $options.

With our custom json:parse function, additional conversion formats are available.

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.

The resulting string can also be created with our custom json:serialize function.

Examples
<map xmlns="http://www.w3.org/2005/xpath-functions">
  <string key="message">world</string>
</map>
=> xml-to-json()
Result: '{"message":"world"}'

fn:element-to-map-plan

Added: New function.

Signature
fn:element-to-map-plan(
  $input  as (document-node() | element())*
) as map(xs:string, map(*))
SummaryAnalyzes the supplied $input nodes and returns a conversion plan suitable for use as the plan option of fn:element-to-map. The returned map contains entries for element and attribute names. Each value is either an fn:element-conversion-plan-record:
record(
  layout  as xs:string,
  child?  as xs:string?,
  type?   as enum('integer', 'decimal', 'double', 'boolean', 'string')
)
or an fn:attribute-conversion-plan-record (for entries prefixed with @):
record(
  type  as enum('integer', 'decimal', 'double', 'boolean', 'string', 'skip')
)
The type is inferred from the string values: integer, decimal or double if all values are numeric, boolean if all values are true/false, and string otherwise. Values with a leading zero (such as 007) are kept as string to preserve their lexical form.
Examples
element-to-map-plan(<a><b>3</b><b>4</b></a>)
The result:
{
  "a": {
    "layout": "list",
    "child": "b"
  },
  "b": {
    "layout": "simple",
    "type": "integer"
  }
}

element-to-map-plan((<a x="2">red</a>, <a x="3">blue</a>))
The result:
{
  "a": {
    "layout": "simple-plus"
  },
  "@x": {
    "type": "integer"
  }
}

let $plan := element-to-map-plan(
  <name><first>Jane</first><last>Smith</last></name>
)
return element-to-map(
  <name><first>John</first><last>Doe</last></name>,
  { 'plan': $plan }
)
Generate a plan from sample data and apply it to a new document. The result:
{
  "name": {
    "first": "John",
    "last": "Doe"
  }
}

fn:element-to-map

Added: New function.

Signature
fn:element-to-map(
  $element  as element()?,
  $options  as map(*)?  := {}
) as map(xs:string, item()?)?
SummaryConverts $element into a map suitable for JSON serialization. The returned map has a single entry whose key is the element name and whose value represents the element’s attributes and children. The $options argument accepts the following keys:
optiondefaultdescription
plan{}A conversion plan, as generated by fn:element-to-map-plan, controlling how individual elements and attributes are converted.
attribute-marker'@'String prepended to keys representing attributes in the output.
content-key'#content'String used in place of #content as the key for content derived from an element’s children. If the chosen key clashes with another key in the generated map, # characters are prepended until it is unique.
name-format'default'Controls how element and attribute names are serialized: lexical, local, eqname, or default.
Examples
element-to-map(<foo>bar</foo>)
Result: { "foo": "bar" }
element-to-map(
  <name>
    <first>Jane</first>
    <last>Smith</last>
  </name>
)
Result: { "name": { "first": "Jane", "last": "Smith" } }
element-to-map(
  <list>
    <item value='1'/>
    <item value='2'/>
  </list>,
  { 'attribute-marker': '' }
)
Result: { "list": [ { "value": "1" }, { "value": "2" } ] }. The empty attribute marker avoids an @ prefix on attribute keys.

Modules

fn:load-xquery-module

Signature
fn:load-xquery-module(
  $module-uri  as xs:string,
  $options     as map(*)?  := {}
) as fn:load-xquery-module-record
Summary

Loads an XQuery library module by its namespace URI and returns a map of its public functions and global variables.

Within $options, the following keys can be specified:

optiondefaultdescription
location-hints()URI(s) of the module.
content()Literal string content of the module. If supplied, location-hints are ignored.
context-item()Initial context item for evaluating global variables.
variables{}Map of external variable bindings.
vendor-options{}Ignored by BaseX.
xquery-versionSpecifies the minimum XQuery version; must be supported by BaseX. Default: version declared in the module, otherwise unspecified.
Examples
let $module := '
  module namespace m = "http://ex.org";
  declare %public function m:two() { 2 };'
let $functions := load-xquery-module(
  'http://ex.org',
  { 'content': $module }
)?functions
let $two := $functions(QName('http://ex.org', 'two'))?0
return $two()
Result: 2
let $uri := 'http://basex.org/modules/code'
let $functions := load-xquery-module(
  $uri,
  { 'location-hints': 'code.xqm' }
)?functions
let $run := $functions(QName($uri, 'run'))(0)
return $run()
Parses code.xqm and evaluates a zero-arity function named run.

fn:transform

Added: New function.

Signature
fn:transform(
  $options  as map(*)
) as map(*)
Summary

Invokes an XSLT transformation and returns a map with a single entry: the key is the base output URI, or the string output; the value is the principal result document. See XSLT Functions for the processors that can be used.

The following $options are available:

optiondefaultdescription
stylesheet-locationURI of the stylesheet. Relative URIs are resolved against the static base URI of the function call.
stylesheet-nodeStylesheet, supplied as document or element node.
stylesheet-textStylesheet, supplied as string. Exactly one of the three stylesheet options must be specified.
stylesheet-base-uriStatic base URI of the stylesheet.
stylesheet-params{}Map with stylesheet parameters. The keys are QNames.
source-locationURI of the source document.
source-nodeSource document, supplied as node. Exactly one of the two source options must be specified.
base-output-uriURI of the principal result document.
delivery-formatdocumentResult format: document (document node), serialized (string) or file (the result is written to the base output URI, and the returned value is an empty sequence).
serialization-params{}Serialization parameters for the principal result document. Parameters that are unknown to the XSLT processor are ignored. As document results are built directly, the option only applies to the delivery formats serialized and file.
post-processFunction that is applied to the key and the value of the result before it is returned.
cachetrue()Cache the compiled stylesheet. Only applies to stylesheets that are supplied by location.
trustedAllow the stylesheet to access external resources (e.g., via xsl:include or document). The default is controlled by the FNXMLTRUSTED option.
xslt-versionRequested XSLT version. An error is raised if no processor with this version is available.

The options enable-assertions, enable-messages, enable-trace and vendor-options are accepted and ignored. All other options of the specification (initial-template, initial-mode, static-params, template-params, the package-* options, etc.) cannot be assigned via the JAXP interface and are rejected with an error, as are the delivery format raw and requested properties other than xsl:version.

Examples
transform({
  'stylesheet-text': "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
    version='1.0'><xsl:template match='/'><out><xsl:value-of
    select='//b'/></out></xsl:template></xsl:stylesheet>",
  'source-node': <a><b>89</b></a>
})?output
Result: <out>89</out>

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

Signature
fn:function-annotations(
  $function  as fn(*)
) as map(xs:QName, xs:anyAtomicType*)*
SummaryReturns the annotations of a $function item as a sequence of single-entry maps. Each map contains one annotation name as its key and the annotation arguments as its value.
Examples
declare
  %public
  %rest:GET
  %rest:path('/')
  %perm:allow('all')
function local:index($n) {
  <html>Welcome!</html>
};
function-annotations(local:index#1)
The result:
{ #xq:public: () },
{ #rest:GET: () },
{ #rest:path: '/' },
{ #perm:allow: 'all' }

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

fn:function-identity

Signature
fn:function-identity(
  $function  as fn(*)
) as xs:string
SummaryReturns a string representing the identity of a $function. The generated string may change when the function is run multiple times.
Examples
function-identity({})
Result: 'map0'
function-identity(abs#1)
Result: 'fn:abs#1'

Higher-Order Functions

fn:filter

Signature
fn:filter(
  $input      as item()*,
  $predicate  as fn($item as item(), $pos as xs:integer) as xs:boolean?
) as item()*
SummaryApplies the boolean $predicate to all items 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

Signature
fn:for-each(
  $input   as item()*,
  $action  as fn($item as item(), $pos as 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

Signature
fn:for-each-pair(
  $input1  as item()*,
  $input2  as item()*,
  $action  as fn($a as item(), $b as item(), $pos as 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

Signature
fn:while-do(
  $input      as item()*,
  $predicate  as fn($value as item()*, $pos as xs:integer) as xs:boolean?,
  $action     as fn($value as item()*, $pos as 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

Signature
fn:do-until(
  $input      as item()*,
  $action     as fn($value as item()*, $pos as xs:integer) as item()*,
  $predicate  as fn($value as item()*, $pos as 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

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 less than or equal to 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(substring#3, [ "abc", 2 ])
Raises an error as the array has only two members.

fn:partial-apply

Signature
fn:partial-apply(
  $function   as fn(*),
  $arguments  as map(xs:positiveInteger, item()*)
) as fn(*)
SummaryReturns a function with selected arguments of $function pre-bound to values in $arguments. The keys in the map denote 1-based positions of the arguments to bind.
Examples
let $char-at := partial-apply(substring#3, { 3: 1 })
return $char-at("abc", 2)
Result: 'b'

fn:op

Signature
fn:op(
  $operator  as xs:string
) as fn($op1 as item()*, $op2 as 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(map:filter(
  { 2: 1234, 3: 3, 4: 5678, 5: 5 },
  op('=')
))
Result: 3, 5. Keeps the entries whose value equals the key, and returns those keys.

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

Signature
fn:fold-left(
  $input   as item()*,
  $init    as item()*,
  $action  as fn($value as item()*, $item as item(), $pos as 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()*,
  $init    as item()*,
  $action  as fn(item()*, item()) as item()*
) as item()* {
  if (empty($input)) then $init
  else fold-left(
    tail($input),
    $action($init, head($input)),
    $action
  )
};

Note: Contrary to the official specification, the current position of the iteration can be retrieved via the third parameter of the higher-order function argument.

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

Signature
fn:fold-right(
  $input   as item()*,
  $init    as item()*,
  $action  as fn($item as item(), $value as item()*, $pos as 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()*,
  $init    as item()*,
  $action  as fn(item(), item()*) as item()*
) as item()* {
  if (empty($input)) then $init
  else $action(
    head($input),
    fold-right(tail($input), $init, $action)
  )
};

Note: Contrary to the official specification, the current position of the iteration can be retrieved via the third parameter of the higher-order function argument.

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

Signature
fn:message(
  $input  as item()*,
  $label  as xs:string?  := ()
) as empty-sequence()
SummaryGenerates a serialized representation of $input, optionally prefixed with $label, and outputs it (see Debugging). 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 outputs it (see Debugging). In contrast to fn:message, the evaluated result is returned unchanged.

Types

fn:atomic-type-annotation

Added: New function.

Signature
fn:atomic-type-annotation(
  $value  as xs:anyAtomicType
) as fn:schema-type-record
SummaryReturns a record with information about the type annotation of $value. The record has the following fields:
  • name: QName of the type
  • is-simple: indicates whether it is a simple type
  • base-type: function returning the annotation of the base type
  • primitive-type: function returning the annotation of the primitive type
  • variety: variety of the type (atomic, list, union or mixed)
  • members: function returning the annotations of the member types
  • simple-content-type: function returning the annotation of the simple content type
  • matches: function testing whether an atomic value is an instance of the type
  • constructor: function constructing a value of the type
Examples
atomic-type-annotation(1e0)?variety
Result: 'atomic'
atomic-type-annotation(xs:byte(1))?base-type()?name => string()
Result: 'short'
atomic-type-annotation(1)?matches(2)
Result: true()
atomic-type-annotation(xs:byte(1))?constructor('127') instance of xs:byte
Result: true()

fn:node-type-annotation

Added: New function.

Signature
fn:node-type-annotation(
  $node  as (element() | attribute())
) as fn:schema-type-record
SummaryReturns a fn:schema-type-record with information about the type annotation of an element or attribute node, with the fields described for fn:atomic-type-annotation. As BaseX is not schema-aware, elements are annotated as xs:untyped and attributes as xs:untypedAtomic.
Examples
node-type-annotation(<a/>)?name => string()
Result: 'untyped'
node-type-annotation(attribute id { 1 })?name => string()
Result: 'untypedAtomic'
node-type-annotation(<a/>)?variety
Result: 'mixed'

fn:schema-type

Added: New function.

Signature
fn:schema-type(
  $name  as xs:QName
) as fn:schema-type-record?
SummaryReturns a fn:schema-type-record with information about the schema type named $name, with the fields described for fn:atomic-type-annotation. An empty sequence is returned if no such type is known; BaseX provides the built-in XSD types.
Examples
schema-type(xs:QName('xs:integer'))?variety
Result: 'atomic'
schema-type(xs:QName('xs:integer'))?base-type()?name => string()
Result: 'decimal'
schema-type(xs:QName('xs:positiveInteger'))?constructor('42')
    instance of xs:positiveInteger
Result: true()
empty(schema-type(xs:QName('unknown-type')))
Result: true()

fn:type-of

Signature
fn:type-of(
  $value  as item()*
) as xs:string
SummaryReturns a string representation of the type of $value. The function is similar to inspect:type.
Examples
type-of('Hello')
Result: 'xs:string'
type-of(1 to 10)
Result: 'xs:integer+'
type-of((1, 'a'))
Result: '(xs:integer|xs:string)+'
type-of(())
Result: 'empty-sequence()'

Miscellaneous

fn:hash

Signature
fn:hash(
  $value      as (xs:string|xs:hexBinary|xs:base64Binary)?,
  $algorithm  as xs:string?  := 'MD5',
  $options    as map(*)?  := {}
) as xs:hexBinary?
SummaryComputes a hash for the given $value, using the specified $algorithm. The supported algorithms are MD5, SHA-1, SHA-256, BLAKE3, and the cyclic redundancy check CRC-32. The $options have no effect in BaseX.
Examples
string(hash(''))
Result: 'D41D8CD98F00B204E9800998ECF8427E'
string(hash('', 'SHA-1'))
Result: 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'
hash('', 'CRC-32') => string()
Result: '00000000'
hash('BaseX', 'CRC-32') => string()
Result: '4C06FC7F'

fn:seconds

Signature
fn:seconds(
  $value  as xs:decimal?  := ()
) as xs:dayTimeDuration?
SummaryReturns a duration for $value, which specifies 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

Signature
fn:default-language() as xs:language
SummaryReturns the default language used for formatting numbers and dates. BaseX always returns en.

fn:system-properties

Added: New function.

Signature
fn:system-properties() as map(xs:QName, xs:anyAtomicType)
SummaryReturns a map with information about the processor. As the map keys are QNames, a property is looked up with ?#name. BaseX supplies the following properties:
  • xpath-version: version of the supported XPath specification
  • xsd-version: version of the supported XML Schema specification
  • product-name: name of the product
  • product-version: version of the product
  • schema-aware: indicates whether schema-awareness is supported
  • accepts-typed-data: indicates whether typed data is accepted
  • supports-xinclude: indicates whether XInclude is supported
  • supports-dtd: indicates whether DTDs are fully supported
  • supports-invisible-xml: indicates whether Invisible XML is available
  • supports-dynamic-xquery: indicates whether dynamic XQuery evaluation is supported
  • supports-dynamic-xslt: indicates whether dynamic XSLT evaluation is supported
Examples
system-properties()?#product-name
Result: 'BaseX'
system-properties()?#xpath-version
Result: 4
sort(map:keys(system-properties()) ! string())
Lists the names of all available properties.

Changelog

Version 13.0Version 12.0Version 11.0

⚡Generated with XQuery