This Appendix describes some sources of functions that fall outside the scope of the function library defined in this specification. It includes both function specifications and function implementations. Inclusion of a function in this appendix does not constitute any kind of recommendation or endorsement; neither is omission from this appendix to be construed negatively. This Appendix does not attempt to give any information about licensing arrangements for these function specifications or implementations.
A number of W3C Recommendations make use of XPath, and in some cases such Recommmendations define additional functions to be made available when XPath is used in a specific host language.
The various versions of XSLT have all included additional functions intended to be available only when XPath is used within XSLT, and not in other host language environments. Some of these functions were originally defined in XSLT, and subsequently migrated into the core function library defined in this specification.
Generally, the reason that functions have been defined in XSLT rather than in the core library has been that they required additional static or dynamic context information.
XSLT-defined functions share the core namespace http://www.w3.org/2005/xpath-functions
(but in XPath 1.0
and XSLT 1.0, no namespace was defined for these functions).
The conformance rules for XSLT 4.0 require implementations to support either XPath 3.0 or XPath 3.1. Some of the new functions in XPath 3.1, however, must be supported by all XSLT 4.0 implementations whether or not they implement other parts of XPath 3.1.
The following table lists all functions that have been defined in XSLT 1.0, 2.0, or 3.0, and summarizes their status.
Function name | Availability |
---|---|
fn:accumulator-after | XSLT 3.0 only |
fn:accumulator-before | XSLT 3.0 only |
fn:available-system-properties | XSLT 3.0 only |
fn:collation-key | Common to XSLT 3.0 and XPath 3.1 |
fn:copy-of | XSLT 3.0 only |
fn:current | XSLT 1.0, 2.0, and 3.0 |
fn:current-group | XSLT 2.0 and 3.0 |
fn:current-grouping-key | XSLT 2.0 and 3.0 |
fn:current-merge-group | XSLT 3.0 only |
fn:current-merge-key | XSLT 3.0 only |
fn:current-output-uri | XSLT 3.0 only |
fn:document | XSLT 1.0, 2.0, and 3.0 |
fn:element-available | XSLT 1.0, 2.0, and 3.0 |
fn:format-date | XSLT 2.0; migrated to XPath 3.0 and 3.1 |
fn:format-dateTime | XSLT 2.0; migrated to XPath 3.0 and 3.1 |
fn:format-number | XSLT 1.0 and 2.0; migrated to XPath 3.0 and 3.1 |
fn:format-time | XSLT 2.0; migrated to XPath 3.0 and 3.1 |
fn:function-available | XSLT 1.0, 2.0, and 3.0 |
fn:generate-id | XSLT 1.0 and 2.0; migrated to XPath 3.0 and 3.1 |
fn:json-to-xml | Common to XSLT 3.0 and XPath 3.1 |
fn:key | XSLT 1.0, 2.0, and 3.0 |
fn:regex-group | XSLT 2.0 and 3.0 |
fn:snapshot | XSLT 3.0 only |
fn:stream-available | XSLT 3.0 only |
fn:system-property | XSLT 1.0, 2.0, and 3.0 |
fn:type-available | XSLT 2.0 and 3.0 |
fn:unparsed-entity-public-id | XSLT 2.0 and 3.0 |
fn:unparsed-entity-uri | XSLT 1.0, 2.0, and 3.0 |
fn:unparsed-text | XSLT 2.0; migrated to XPath 3.0 and 3.1 |
fn:xml-to-json | Common to XSLT 3.0 and XPath 3.1 |
map:contains | Common to XSLT 3.0 and XPath 3.1 |
map:entry | Common to XSLT 3.0 and XPath 3.1 |
map:find | Common to XSLT 3.0 and XPath 3.1 |
map:for-each | Common to XSLT 3.0 and XPath 3.1 |
map:get | Common to XSLT 3.0 and XPath 3.1 |
map:keys | Common to XSLT 3.0 and XPath 3.1 |
map:merge | Common to XSLT 3.0 and XPath 3.1 |
map:put | Common to XSLT 3.0 and XPath 3.1 |
map:remove | Common to XSLT 3.0 and XPath 3.1 |
map:size | Common to XSLT 3.0 and XPath 3.1 |
XForms 1.1 is based on XPath 1.0. It adds the following functions to the set defined in XPath 1.0, using the same namespace:
boolean-from-string
, is-card-number
, avg
, min
, max
,
count-non-empty
, index
, power
, random
, compare
,
if
, property
,
digest
, hmac
, local-date
, local-dateTime
, now
,
days-from-date
, days-to-date
, seconds-from-dateTime
, seconds-to-dateTime
,
adjust-dateTime-to-timezone
, seconds
, months
, instance
,
current
, id
, context
, choose
, event
.
XForms 2.0 was first published as a W3C Working Draft, and subsequently as a W3C Community Group specification. These draft specifications do not include any additional functions beyond those in the core XPath specification.
The XQuery Update 1.0 specification defines one additional function in the core namespace
http://www.w3.org/2005/xpath-functions
, namely fn:put
. This function can be used
to write a document to external storage. It is thus unusual in that it has side-effects; the XQuery Update 1.0
specification defines semantics for updating expressions including this function.
Although XQuery Update 1.0 is defined as an extension of XQuery 1.0, a number of implementors have adapted it, in a fairly intuitive way, to work with later versions of XQuery. At the time of this publication, later versions of the XQuery Update specification remain at Working Draft status.
A number of community groups, with varying levels of formal organization, have defined specifications for additional function libraries to augment the core functions defined in this specification. Many of the resulting function specifications have implementations available for popular XPath, XQuery, and XSLT processors, though the level of support is highly variable.
The first such group was EXSLT. This activity was primarily concerned with augmenting the capability of XSLT 1.0, and many of its specifications were overtaken by core functions that became available in XPath 2.0. EXSLT defined a number of function modules covering:
Dates and Times
Dynamic XPath Evaluation
Common (containing most notably the widely usednode-set
function)
Math (max
,min
,abs
, and trigonometric functions)
Random Number Generation
Regular Expressions
Sets (operations on sets of nodes including set intersection and difference)
String Manipulation (tokenize, replace, join and split, etc.)
Specifications from the EXSLT group can be found at [EXSLT].
A renewed attempt to define additional function libraries using XPath 2.0 as its baseline formed under the name EXPath. Again, the specifications are in various states of maturity and stability, and implementation across popular processors is patchy. At the time of this publication the function libraries that exist in stable published form include:
Binary (functions for manipulating binary data)
File Handling (reading and writing files)
Geospatial (handling of geographic data)
HTTP Client (sending HTTP requests)
ZIP Facility (reading and creating ZIP files or similar archives)
The EXPath community has also been engaged in other related projects, such as defining packaging standards for distribution of XSLT/XQuery components, and tools for unit testing. Its specifications can be found at [EXPath].
A third activity has operated under the name EXQuery, which as the name suggests has focused on extensions to XQuery. EXQuery has published a single specification, RestXQ, which is primarily a system of function annotations allowing XQuery functions to act as endpoints for RESTful services. It also includes some simple functions to assist with the creation of such services. The RestXQ specification can be found at [EXQuery].
Many useful functions can be written in XSLT or XQuery, and in this case the function implementations themselves can be portable across different XSLT and XQuery processors. This section describes one such library.
FunctX is an open-source library of general-purpose functions, supplied in the form of XQuery 1.0 and XSLT 2.0 implementations. It contains over a hundred functions. Typical examples of these functions are:
Test whether a string is all-whitespace
Trim leading and trailing whitespace
Test whether all the values in a sequence are distinct
Capitalize the first character of a string
Change the namespace of all elements in a tree
Get the number of days in a given month
Get the first or last day in a given month
Get the date of the preceding or following day
Ask whether an element has element-only, mixed, or simple content
Find the position of a node in a sequence
Count words in a string
The FunctX library can be found at [FunctX].
Certain functions that were proposed for inclusion in this function library have been excluded on the basis that it is straightforward for users to implement these functions themselves using XSLT 2.0 or XQuery 1.0.
This Appendix provides sample implementations of some of these functions.
To emphasize that these functions are examples of functions that vendors may write, their names carry the prefix 'eg'. Vendors are free to define such functions in any namespace. A group of vendors may also choose to create a collection of such useful functions and put them in a common namespace.
In some situations, users may want to provide default values for missing
information that may be signaled by elements that are omitted, have no value or
have the empty sequence as their value. For example, a missing middle initial
may be indicated by omitting the element or a non-existent bonus signaled with
an empty sequence. This section includes examples of functions that provide such
defaults. These functions return xs:anyAtomicType*
. Users may want
to write functions that return more specific types.
eg:if-empty ( |
||
$node |
as node() , |
|
$value |
as xs:anyAtomicType |
|
) as xs:anyAtomicType* |
If the first argument is the empty sequence or an element without simple or
complex content, eg:if-empty()
returns the second argument; otherwise, it
returns the content of the first argument.
XSLT implementation
<xsl:function name="eg:if-empty" as="xs:anyAtomicType*"> <xsl:param name="node" as="node()?"/> <xsl:param name="value" as="xs:anyAtomicType"/> <xsl:sequence select="($node[child::node()], $value)[1]"/> </xsl:function>
XQuery implementation
declare function eg:if-empty ( $node as node()?, $value as xs:anyAtomicType) as xs:anyAtomicType* { ($node[child::node()], $value)[1] }
eg:if-absent ( |
||
$node |
as node() , |
|
$value |
as xs:anyAtomicType |
|
) as xs:anyAtomicType* |
If the first argument is the empty sequence, eg:if-absent()
returns the second
argument; otherwise, it returns the content of the first argument.
XSLT implementation
<xsl:function name="eg:if-absent" as="xs:anyAtomicType*"> <xsl:param name="node" as="node()?"/> <xsl:param name="value" as="xs:anyAtomicType"/> <xsl:sequence select="($node, $value)[1]"/> </xsl:function>
XQuery implementation
declare function eg:if-absent ( $node as node()?, $value as xs:anyAtomicType) as xs:anyAtomicType* { ($node, $value)[1] }
eg:value-union ( |
||
$arg1 |
as xs:anyAtomicType* , |
|
$arg2 |
as xs:anyAtomicType* |
|
) as xs:anyAtomicType* |
This function returns a sequence containing all the distinct items in $arg1
and $arg2
, in an arbitrary order.
XSLT implementation
<xsl:function name="eg:value-union" as="xs:anyAtomicType*"> <xsl:param name="arg1" as="xs:anyAtomicType*"/> <xsl:param name="arg2" as="xs:anyAtomicType*"/> <xsl:sequence select="fn:distinct-values(($arg1, $arg2))"/> </xsl:function>
XQuery implementation
declare function eg:value-union ( $arg1 as xs:anyAtomicType*, $arg2 as xs:anyAtomicType*) as xs:anyAtomicType* { fn:distinct-values(($arg1, $arg2)) }
eg:value-intersect ( |
||
$arg1 |
as xs:anyAtomicType* , |
|
$arg2 |
as xs:anyAtomicType* |
|
) as xs:anyAtomicType* |
This function returns a sequence containing all the distinct items that
appear in both $arg1
and $arg2
, in an arbitrary order.
XSLT implementation>
<xsl:function name="eg:value-intersect" as="xs:anyAtomicType*"> <xsl:param name="arg1" as="xs:anyAtomicType*"/> <xsl:param name="arg2" as="xs:anyAtomicType*"/> <xsl:sequence select="fn:distinct-values($arg1[.=$arg2])"/> </xsl:function>
XQuery implementation
declare function eg:value-intersect ( $arg1 as xs:anyAtomicType*, $arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* { fn:distinct-values($arg1[.=$arg2]) }
eg:value-except ( |
||
$arg1 |
as xs:anyAtomicType* , |
|
$arg2 |
as xs:anyAtomicType* |
|
) as xs:anyAtomicType* |
This function returns a sequence containing all the distinct items that
appear in $arg1
but not in $arg2
, in an arbitrary order.
XSLT implementation
<xsl:function name="eg:value-except" as="xs:anyAtomicType*"> <xsl:param name="arg1" as="xs:anyAtomicType*"/> <xsl:param name="arg2" as="xs:anyAtomicType*"/> <xsl:sequence select="fn:distinct-values($arg1[not(.=$arg2)])"/> </xsl:function>
XQuery implementation
declare function eg:value-except ( $arg1 as xs:anyAtomicType*, $arg2 as xs:anyAtomicType*) as xs:anyAtomicType* { fn:distinct-values($arg1[not(.=$arg2)]) }
eg:index-of-node ( |
||
$seq |
as node()* , |
|
$search |
as node() |
|
) as xs:integer* |
This function returns a sequence of positive integers giving the positions within
the sequence $seq
of nodes that are identical to $search
.
The nodes in the sequence $seq
are compared with
$search
under the rules for the is
operator. If a
node compares identical, then the position of that node in the sequence
$seq
is included in the result.
If the value of $seq
is the empty sequence, or if no node in
$seq
matches $search
, then the empty sequence is returned.
The index is 1-based, not 0-based.
The result sequence is in ascending numeric order.
XSLT implementation
<xsl:function name="eg:index-of-node" as="xs:integer*"> <xsl:param name="seq" as="node()*"/> <xsl:param name="search" as="node()"/> <xsl:sequence select="filter( 1 to count($seq), function($i as xs:integer) as xs:boolean {$seq[$i] is $search} ) "/> </xsl:function>
XQuery implementation
declare function eg:index-of-node($seq as node()*, $search as node()) as xs:integer* { fn:filter( 1 to fn:count($seq), function($i as xs:integer) as xs:boolean {$seq[$i] is $search} ) }
An alternative implementation, which might be faster in systems where indexing into a sequence is slow, is:
declare function eg:index-of-node($seq as node()*, $search as node()) as xs:integer* { fn:for-each-pair( $seq, 1 to fn:count($seq), function($node, $index) { if($node is $search) then $index else () }) }
eg:string-pad ( |
||
$padString |
as xs:string , |
|
$padCount |
as xs:integer |
|
) as xs:string |
Returns a xs:string
consisting of a given number of copies of an
xs:string
argument concatenated together.
XSLT implementation
<xsl:function name="eg:string-pad" as="xs:string"> <xsl:param name="padString" as="xs:string?"/> <xsl:param name="padCount" as="xs:integer"/> <xsl:sequence select=" fn:string-join(1 to $padCount ! $padString)"/> </xsl:function>
XQuery implementation
declare function eg:string-pad ( $padString as xs:string?, $padCount as xs:integer) as xs:string { fn:string-join(1 to $padCount ! $padString) }
This returns the zero-length string if $padString
is the empty
sequence, which is consistent with the general principle that if an
xs:string
argument is the empty sequence it is treated as if it
were the zero-length string.
eg:distinct-nodes-stable ( |
||
$arg |
as node()* |
|
) as node()* |
This function illustrates one possible implementation of a distinct-nodes function. It removes duplicate nodes by identity, preserving the first occurrence of each node.
XPath
$arg[empty(subsequence($arg, 1, position()-1) intersect .)]
XSLT implementation
<xsl:function name="eg:distinct-nodes-stable" as="node()*"> <xsl:param name="arg" as="node()*"/> <xsl:sequence select="" fn:fold-left( $arg, (), function($foundSoFar as node()*, $this as node()) as node()* { if ($foundSoFar intersect $this) then $foundSoFar else ($foundSoFar, $this) }) "/> </xsl:function>
XQuery implementation
declare function eg:distinct-nodes-stable ($arg as node()*) as node()* { fn:fold-left( $arg, (), function($foundSoFar as node()*, $this as node()) as node()* { if ($foundSoFar intersect $this) then $foundSoFar else ($foundSoFar, $this) }) };