0% found this document useful (0 votes)
99 views

Marklogic Server: Xquery and XSLT Reference Guide

Uploaded by

Abdullah Yahya
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
99 views

Marklogic Server: Xquery and XSLT Reference Guide

Uploaded by

Abdullah Yahya
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 98

MarkLogic Server

XQuery and XSLT Reference Guide


1

MarkLogic 10
May, 2019

Last Revised: 10.0, May, 2019

Copyright © 2019 MarkLogic Corporation. All rights reserved.


MarkLogic Server Table of Contents

Table of Contents

XQuery and XSLT Reference Guide

1.0 About This XQuery and XSLT Guide ...........................................................6

2.0 XQuery Dialects in MarkLogic Server ..........................................................7


2.1 Overview of the XQuery Dialects ..........................................................................7
2.1.1 MarkLogic Server Enhanced (XQuery 1.0-ml) ..........................................7
2.1.2 Strict (XQuery 1.0) .....................................................................................7
2.2 Rules For Combining the Dialects ..........................................................................8
2.3 Using a Non-Default Dialect in XSLT (xdmp:dialect) ...........................................8
2.4 Strategies For Migrating Code to Enhanced Dialect ..............................................8
2.4.1 When To Migrate XQuery Code ................................................................9
2.4.2 XQuery Changes from 0.9-ml to 1.0-ml .....................................................9
2.4.2.1 Syntax Changes from XQuery 0.9-ml to XQuery 1.0-ml .........10
2.4.2.2 Semantic Changes from XQuery 0.9-ml to XQuery 1.0-ml .....10
2.4.2.3 Changes to Built-in Definitions .................................................11
2.4.3 Inheriting the Default XQuery Version From the App Server .................13
2.5 Specifying the XQuery Dialect in the Prolog .......................................................13
2.5.1 Porting 0.9-ml XQuery Code to Enhanced 1.0-ml ...................................13

3.0 MarkLogic Server Enhanced XQuery Language .........................................15


3.1 try/catch Expression ..............................................................................................15
3.2 Function Mapping .................................................................................................17
3.2.1 Understanding Function Mapping ............................................................17
3.2.2 Enabling or Disabling Function Mapping ................................................18
3.3 Semi-Colon as Transaction Separator ...................................................................19
3.4 Private Function and Variable Definitions ...........................................................19
3.5 Functions With Side Effects .................................................................................19
3.6 Shorthand Positional Predicate Syntax .................................................................20
3.7 Binary Node Constructor and Node Test ..............................................................20
3.8 validate as Expression ...........................................................................................20
3.9 Serialization Options .............................................................................................20
3.10 Importing a Stylesheet Into an XQuery Module ...................................................21
3.11 XQuery 3.x Features .............................................................................................21
3.11.1 Arrow Operator .........................................................................................22
3.11.2 Simple Map Operator ................................................................................23
3.11.3 String Concatenation Operator .................................................................23
3.11.4 URI Qualified Names ...............................................................................23
3.11.5 Dynamic Function Invocation ..................................................................24
3.11.6 Inline Functions ........................................................................................24

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 2


MarkLogic Server Table of Contents

3.11.7 Function Type Testing ..............................................................................24


3.11.8 Named Function References .....................................................................25
3.11.9 Partial Function Application .....................................................................25
3.11.10Function Annotations ................................................................................26
3.11.11Default Values for External Variables ......................................................26
3.11.12Unions in Typeswitch Case Descriptors ...................................................26
3.11.13Switch Statement ......................................................................................27
3.11.14Validate Type Expressions .......................................................................27
3.11.15Error Handling with Try/Catch .................................................................28
3.12 Implementation-Defined Semantics .....................................................................28
3.12.1 Automatic Namespace Imports for Predefined Namespaces ....................29
3.12.2 Namespace path ........................................................................................29
3.12.3 External Variables .....................................................................................29
3.12.4 Collations ..................................................................................................30
3.12.5 Implementation-Defined Primitive XQuery Types ..................................31
3.12.6 Decimal Precision at Least 18 Digits, and is Not Configurable ...............31
3.12.7 Library Modules Default Function Namespace Defaults to Library
Namespace 31

4.0 XQuery Language ........................................................................................32


4.1 Expressions Return Items .....................................................................................32
4.2 XML and XQuery .................................................................................................33
4.2.1 Direct Element Constructors: Switching Between XQuery and XML Using
Curly Braces 33
4.2.2 Computed Element and Attribute Constructors ........................................34
4.2.3 Returning XML From an XQuery Program .............................................35
4.3 JSON and XQuery ................................................................................................35
4.4 XQuery Modules ...................................................................................................35
4.4.1 XQuery Version Declaration ....................................................................35
4.4.2 Main Modules ...........................................................................................36
4.4.3 Library Modules .......................................................................................36
4.5 XQuery Prolog ......................................................................................................37
4.5.1 Importing Modules or Schemas ................................................................37
4.5.2 Declaring Namespaces ..............................................................................38
4.5.3 Declaring Options .....................................................................................38
4.5.3.1 xdmp:mapping ...........................................................................38
4.5.3.2 xdmp:update ..............................................................................38
4.5.3.3 xdmp:commit ............................................................................39
4.5.3.4 xdmp:transaction-mode .............................................................39
4.5.3.5 xdmp:copy-on-validate ..............................................................40
4.5.3.6 xdmp:output ..............................................................................40
4.5.3.7 xdmp:coordinate-system ...........................................................42
4.5.4 Declaring Functions ..................................................................................42
4.5.5 Declaring Variables ..................................................................................42
4.5.6 Declaring a Default Collation ...................................................................43
4.6 XQuery Comments ...............................................................................................43

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 3


MarkLogic Server Table of Contents

4.7 XQuery Expressions .............................................................................................44


4.7.1 XPath Expressions ....................................................................................44
4.7.2 FLWOR Expressions ................................................................................44
4.7.2.1 The for Clause ...........................................................................45
4.7.2.2 The let Clause ............................................................................46
4.7.2.3 The where Clause ......................................................................47
4.7.2.4 The order by Clause ..................................................................48
4.7.2.5 The return Clause ......................................................................49
4.7.3 The typeswitch Expression .......................................................................49
4.7.4 The if Expression ......................................................................................50
4.7.5 Quantified Expressions (some/every ... satisfies ...) .................................51
4.7.6 Validate Expression ..................................................................................52
4.8 XQuery Comparison Operators ............................................................................53
4.8.1 Node Comparison Operators ....................................................................53
4.8.2 Sequence and Item Operators ...................................................................54
4.8.2.1 Sequence Operators ...................................................................54
4.8.2.2 Item Operators ...........................................................................55

5.0 XPath Quick Reference ................................................................................57


5.1 Path Expressions ...................................................................................................57
5.2 XPath Axes and Syntax ........................................................................................58
5.3 XPath 2.0 Functions ..............................................................................................59
5.4 Restricted XPath ...................................................................................................59
5.4.1 Path Field and Path-Based Range Index Configuration ...........................60
5.4.2 Element Level Security .............................................................................62
5.4.3 Template Driven Extraction (TDE) ..........................................................62
5.4.4 Patch Feature of the Client APIs ...............................................................63
5.4.5 The extract-document-data Query Option ................................................65
5.4.6 The Optic API xpath Function ..................................................................65
5.4.7 Functions Callable in Predicate Expressions ............................................66
5.4.7.1 String Functions ........................................................................66
5.4.7.2 Logical and Data Validation Functions .....................................66
5.4.7.3 Date and Time Functions ..........................................................67
5.4.7.4 Type Casting Functions .............................................................67
5.4.7.5 Mathematical Functions ............................................................68
5.4.7.6 Miscellanious Functions ............................................................68
5.4.8 Indexable Path Expression Grammar .......................................................69
5.4.9 Patch and Extract Path Expression Grammar ...........................................71

6.0 Understanding XML Namespaces in XQuery .............................................73


6.1 XML QNames, Local Names, and Namespaces ...................................................73
6.2 Everything Is In a Namespace ..............................................................................73
6.3 XML Data Model Versus Serialized XML ...........................................................74
6.3.1 XQuery Accesses the XML Data Model ..................................................74
6.3.2 Serialized XML: Human-Readable With Angle Brackets ........................74

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 4


MarkLogic Server Table of Contents

6.3.3 Understanding Namespace Inheritance With the xmlns Attribute ...........76


6.4 Declaring a Default Element Namespace in XQuery ...........................................78
6.5 Tips For Constructing QNames ............................................................................78
6.6 Predefined Namespace Prefixes for Each Dialect ................................................79
6.6.1 1.0-ml Predefined Namespaces .................................................................79
6.6.2 1.0 Predefined Namespaces ......................................................................81

7.0 XSLT in MarkLogic Server .........................................................................83


7.1 XSLT 2.0 ..............................................................................................................83
7.2 Invoking and Evaluating XSLT Stylesheets .........................................................83
7.3 MarkLogic Server Extensions to XSLT ...............................................................84
7.3.1 Calling Built-In XQuery Functions in a Stylesheet ..................................84
7.3.2 Importing XQuery Function Libraries to a Stylesheet ..............................84
7.3.3 Try/Catch XSLT Instruction .....................................................................85
7.3.4 EXSLT Extensions ...................................................................................85
7.3.5 xdmp:dialect Attribute ..............................................................................86
7.3.6 Notes on Importing Stylesheets With <xsl:import> .................................87
7.4 Invoking Stylesheets Directly Using the XSLT Rewriter ....................................87
7.4.1 About the Sample Rewriter .......................................................................87
7.4.2 Setting Up the Sample Rewriter in Your HTTP App Server ....................89
7.5 XSLT, XQuery, or Both .......................................................................................89

8.0 Application Programming in XQuery and XSLT ........................................90


8.1 Design Patterns .....................................................................................................90
8.2 Using Functions ....................................................................................................90
8.2.1 Creating Reusable and Modular Code ......................................................91
8.2.2 Recursive Functions ..................................................................................91
8.3 Search Functions ...................................................................................................92
8.4 Updates and Transactions .....................................................................................92
8.5 HTTP App Server Functions ................................................................................92
8.6 Additional Resources ............................................................................................93
8.6.1 MarkLogic Server Documentation ...........................................................93
8.6.2 XQuery Use Cases ....................................................................................93
8.6.3 Other Publications .....................................................................................94

9.0 Technical Support ........................................................................................95

10.0 Copyright .....................................................................................................97

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 5


MarkLogic Server About This XQuery and XSLT Guide

1.0 About This XQuery and XSLT Guide


6

This XQuery and XSLT Reference Guide briefly describes some of the basics of the XQuery
language, but describes more thoroughly the MarkLogic Server implementation of XQuery,
including many of the important extensions to the language implemented in MarkLogic Server.
Additionally, it describes how to invoke XSLT stylesheets and briefly describes the MarkLogic
Server XSLT 2.0 implementation.

The next two chapters (“XQuery Dialects in MarkLogic Server” on page 7 and “MarkLogic
Server Enhanced XQuery Language” on page 15) focus on the MarkLogic Server-specific aspects
of the XQuery language. If you prefer to start with the more generic aspects of the XQuery
language before moving to the MarkLogic Server-specific parts, start with “XQuery Language”
on page 32.

Specifically, this guide covers:

• The different dialects of XQuery supported in MarkLogic Server (see “XQuery Dialects in
MarkLogic Server” on page 7).
• MarkLogic extensions to the XQuery language (see “MarkLogic Server Enhanced
XQuery Language” on page 15).
• An overview of the basic syntax of the XQuery language (see “XQuery Language” on
page 32).
• A brief description of XPath syntax (see “XPath Quick Reference” on page 57).
• An introduction to how namespaces work in XML and XQuery (see “Understanding XML
Namespaces in XQuery” on page 73).
• Using XSLT in MarkLogic Server (see “XSLT in MarkLogic Server” on page 83).
• Some information on how XQuery and XSLT are used as application development
programming languages in MarkLogic Server (see “Application Programming in XQuery
and XSLT” on page 90).

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 6


MarkLogic Server XQuery Dialects in MarkLogic Server

2.0 XQuery Dialects in MarkLogic Server


14

The XQuery specification is a formal recommendation from the W3C XQuery Working Group.
MarkLogic 10 implements the W3C XQuery 1.0 Recommendation (http://www.w3.org/TR/xquery/).
To maximize compatibility with MarkLogic Server and to offer strict XQuery compliance to
those who desire it, as well as to include extensions to the language to make it easier to build
applications, MarkLogic Server supports two dialects of XQuery. This chapter describes these
dialects, and includes the following sections:

• Overview of the XQuery Dialects

• Rules For Combining the Dialects

• Using a Non-Default Dialect in XSLT (xdmp:dialect)

• Strategies For Migrating Code to Enhanced Dialect

2.1 Overview of the XQuery Dialects


MarkLogic Server supports the following dialects of XQuery:

• MarkLogic Server Enhanced (XQuery 1.0-ml)

• Strict (XQuery 1.0)

You can use library modules from different dialects together, as described in “Rules For
Combining the Dialects” on page 8. Each dialect has a different set of pre-defined namespaces, as
described in “Predefined Namespace Prefixes for Each Dialect” on page 79.

2.1.1 MarkLogic Server Enhanced (XQuery 1.0-ml)


For a module to use the MarkLogic Server enhanced dialect, use the following for the XQuery
version declaration on the first line of the XQuery module:

xquery version "1.0-ml";

Note the semi-colon at the end of the declaration, which is required in 1.0-ml. The enhanced
dialect has the XQuery 1.0 syntax and also includes various extensions to the language such as
try/catch. This dialect is the default for new App Servers, and is considered the preferred dialect
for new applications. For more details on the enhanced 1.0-ml dialect, see “MarkLogic Server
Enhanced XQuery Language” on page 15.

2.1.2 Strict (XQuery 1.0)


For a module to use the MarkLogic Server strict dialect (1.0), use the following for the XQuery
version declaration on the first line of the XQuery module:

xquery version "1.0";

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 7


MarkLogic Server XQuery Dialects in MarkLogic Server

Note the semi-colon at the end of the declaration, which is required in 1.0. The strict mode is for
compatibility with other XQuery 1.0 processors; if you write a library in 1.0, you can use it with
MarkLogic Server and you can also use it with other conforming processors. Similarly, you can
use modules that are written in standard XQuery with MarkLogic Server.

To use the MarkLogic Server built-in functions in 1.0, you must bind a prefix (for example, xdmp)
to the namespace for the MarkLogic Server functions; there is no need to import a library for
these built-in functions, but you do need to bind the namespace to a prefix. To use the xdmp
functions in 1.0, add prolog entries for the namespace bindings you are using in your query, as in
the following example:

xquery version "1.0";


declare namespace xdmp = "http://marklogic.com/xdmp";

xdmp:version()

2.2 Rules For Combining the Dialects


MarkLogic Server has a very flexible way of combining the different XQuery dialects. You can
import a library module written in any of the three dialects into any main or library module. For
example, you might find an open source standards-compliant module that you found on the
internet which is written in the strict XQuery 1.0 dialect. You can then import this module into
any MarkLogic Server XQuery program, regardless of dialect, and then use those functions in
your code.

When writing modules of different dialects, the best practice is to always use the XQuery version
declaration as the first line, indicating which dialect the module is written in. That way, if the
module is written in a different dialect than the default dialect for the App Server or the program,
it will still work correctly (for details, see “Inheriting the Default XQuery Version From the App
Server” on page 13).

2.3 Using a Non-Default Dialect in XSLT (xdmp:dialect)


You can use the xdmp:dialect attribute to specify which dialect expressions are evaluated in an
XSLT stylesheet. For details, see “xdmp:dialect Attribute” on page 86.

2.4 Strategies For Migrating Code to Enhanced Dialect


If you are writing new XQuery code, the best practice is to use the 1.0-ml dialect. If you are
updating code that was written in previous versions of MarkLogic Server, migrate that code to
1.0-ml. This section describes things to think about when migrating your application code and
includes the following parts:

• When To Migrate XQuery Code

• XQuery Changes from 0.9-ml to 1.0-ml

• Inheriting the Default XQuery Version From the App Server

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 8


MarkLogic Server XQuery Dialects in MarkLogic Server

• Porting 0.9-ml XQuery Code to Enhanced 1.0-ml

2.4.1 When To Migrate XQuery Code


XQuery 0.9-ml has been deprecated and will be removed in a future release. If you have code
written in XQuery dialect 0.9-ml, you need to migrate your XQuery code to either enhanced
XQuery 1.0-ml or strict XQuery 1.0. The differences between the dialects are mostly syntax
changes in the prolog, but there are also some other differences that might cause subtle changes in
behavior. For details on the differences between the XQuery dialects in 0.9-ml and 1.0-ml, see
“XQuery Changes from 0.9-ml to 1.0-ml” on page 9. When you migrate XQuery code to 1.0-ml
(or to 1.0), there are several ways you can go about it:

• Migrate an entire application all at once. This method gets everything over with at once,
and therefore focuses the effort. If you have a relatively small amount of code to migrate,
it might make sense to just go ahead and migrate it all at once.
• Migrate one module at a time. This method allows you to spread the migration work over
a number of small tasks instead of one large task, and further allows you to test each
module independently after migration. This technique is very flexible, as you can do a
little bit at a time. A good first step for this one-by-one approach is to start by adding an
XQuery 0.9-ml declaration to the first line of each XQuery file. Then, as you migrate a
module, you can change the declaration to 1.0-ml and make any needed syntax changes to
that module.

2.4.2 XQuery Changes from 0.9-ml to 1.0-ml

Note: MarkLogic has deprecated XQuery 0.9-ml and will be removing it in a future
release.

While MarkLogic Server currently allows 0.9-ml code to run without changes, the dialect is
deprecated and will be removed in a future release. The new XQuery dialect 1.0-ml has
enhancements. Because you can mix modules in the old dialect with modules in the new, you can
perform your migration one module at a time. This section highlights the major syntax and
semantic changes between the XQuery used in 0.9-ml and enhanced XQuery dialect 1.0-ml. The
changes fall into the following categories:

• Syntax Changes from XQuery 0.9-ml to XQuery 1.0-ml

• Semantic Changes from XQuery 0.9-ml to XQuery 1.0-ml

• Changes to Built-in Definitions

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 9


MarkLogic Server XQuery Dialects in MarkLogic Server

2.4.2.1 Syntax Changes from XQuery 0.9-ml to XQuery 1.0-ml


The following syntax has changed from XQuery 0.9-ml to XQuery 1.0-ml:

• Semi-colons ( ; ) are now required at the end of each prolog declaration.


• Prolog declarations that previously used define now use declare.
• Variable declaration syntax is slightly different, and now uses the := syntax (for details
and an example, see “Declaring Variables” on page 42).

2.4.2.2 Semantic Changes from XQuery 0.9-ml to XQuery 1.0-ml


The following semantic changes have occurred from XQuery 0.9-ml to XQuery 1.0-ml:

• If you are modifying a main module and it has function declarations that are used in the
same module, they must be declared in a namespace. Library module declarations now
require the namespace keyword and a prefix for the namespace, for example:

module namespace my = "my-namespace";

Note: Functions in a main module must be put into the local: namespace.

• Function declarations that return the empty sequence now require the empty sequence to
be specified as follows:

empty-sequence()

The 0.9-ml dialect had you specify empty() for the empty sequence.

• Some of the effective boolean value rules have changed. Notably, the following returns
true in 0.9-ml and returns false in 1.0-ml (and throws an exception in 1.0):

(: returns true in 0.9-ml, false in 1.0-ml, and


throws XDMP-EFFBOOLVALUE in 1.0 :)
fn:boolean((fn:false(), fn:false()))

This change might affect applications that have if/then/else statements where the if test
returns a sequence of boolean values. In these cases, you might see the if statement
evaluating to false in cases where it previously evaluated to true, causing the else
statement to be evaluated intead of the then statement.

• String functions treat empty arguments as equivalent. For example, the following
statements, while not equivalent, are treated the same:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 10


MarkLogic Server XQuery Dialects in MarkLogic Server

substring((), 1);
substring("",1)

In the first line, “()” is parsed identically to “""” in the second line.

The functions affected by this are:

fn:starts-with fn:ends-with fn:contains fn:substring


fn:substring-before fn:substring-after fn:string-length fn:upper-case
fn:lower-case fn:normalize-space fn:normalize-unicode fn:translate
fn:tokenize fn:replace fn:matches

• Constraints on timezone min and max offsets are now enforced.


• Range expressions in which the lower bound is greater than the upper bound are no longer
treated as a range. For example, [5 to 1] is now evaluated as “()”.
• The namespace used for durations now uses the xs namespace prefix; previously it used
the xdt prefix. Any code you have that uses the xdt namespace prefix will require a
change to the xs prefix. For example, if you have code that uses xdt:dayTimeDuration,
change it to xs:dayTimeDuration.
• element() tests in 0.9-ml are equivalent to schema-element() test in 1.0 and 1.0-ml. Any
code you have with element() tests might not match some elements that previously
matched. For example, substitution elements previously would match the base element
name, but will now only match with schema-element() test in 1.0 and 1.0-ml.
• XQuery 1.0-ml has has function mapping enabled by default.
• Some changes to the XQuery standard functions. For example, there are subtle changes to
fn:avg and fn:sum, fn:error has a different signature, and fn:node-kind does not exist in
1.0 and 1.0-ml (it is replaced by xdmp:node-kind).

2.4.2.3 Changes to Built-in Definitions


The following built-in functions have changed:

• fn:translate: The second and third arguments can no longer be empty.


• fn:error: The signature has changed. For details, see:
https://www.w3.org/TR/xpath-functions/#func-error

• fn:resolve-uri: XQuery 1.0-ml has implemented this function differently. It is more


likely to throw an error when it has trouble resolving a relative URI reference.
• The following function names have changed:
XQuery 0.9-ml Function XQuery 1.0-ml Function
fn:get-local-name-from-QName fn:local-name-from-QName
fn:input fn:doc
fn:expanded-QName fn:QName

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 11


MarkLogic Server XQuery Dialects in MarkLogic Server

XQuery 0.9-ml Function XQuery 1.0-ml Function


fn:node-kind xdmp:node-kind
fn:get-minutes-from-dayTimeDuration fn:minutes-from-duration
fn:get-month-from-date fn:month-from-date
fn:get-seconds-from-dateTime fn:seconds-from-dateTime
fn:get-year-from-dateTime fn:year-from-dateTime
fn:get-day-from-date fn:day-from-date
fn:get-seconds-from-dayTimeDuration fn:seconds-from-dayTimeDuration
fn:get-year-from-date fn:year-from-date
fn:get-days-from-duration fn:days-from-duration
fn:get-timezone-from-date fn:timezone-from-date
fn:get-namespace-uri-from-QName fn:namespace-uri-from-QName
fn:get-seconds-from-time fn:seconds-from-time
fn:get-minutes-from-time fn:minutes-from-time
fn:get-timezone-from-time fn:timezone-from-time
fn:get-hours-from-dateTime fn:hours-from-dateTime
fn:get-months-from-yearMonthDuration fn:months-from-duration
fn:get-day-from-dateTime fn:day-from-dateTime
fn:get-month-from-dateTime fn:month-from-dateTime
fn:get-hours-from-dayTimeDuration fn:hours-from-duration
fn:get-minutes-from-dateTime fn:minutes-from-dateTime
fn:get-years-from-yearMonthDuration fn:years-from-duration
fn:get-hours-from-time fn:hours-from-time
fn:get-timezone-from-dateTime fn:timezone-from-dateTime
fn:get-namespace-uri-for-prefix fn:namespace-uri-for-prefix
fn:get-in-scope-namespaces fn:in-scope-prefixes

• The following functions are no longer supported:


• fn:subtract-dateTimes-yielding-dayTimeDuration
Use the minus sign operator (“-”).
• fn:distinct-nodes
You must now write an XQuery loop to replace this function.
• fn:subtract-dateTimes-yielding-yearMonthDuration
Use the minus sign (“-”) operator to get xs:dayTimeDuration.
• fn:string-pad
You must now write an XQuery loop to replace this function.
• fn:context-item
Use “.” or fn:current() as appropriate.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 12


MarkLogic Server XQuery Dialects in MarkLogic Server

2.4.3 Inheriting the Default XQuery Version From the App Server
Each App Server has a setting for the default XQuery version. Any requests against that App
Server that do not have explicitly specify an XQuery version declaration are treated as the default
XQuery version value. Because of the way a request inherits it default XQuery version from the
App Server environment, requests without an explicit declaration can be treated differently by
different App Servers (if the App Servers have different default XQuery values). Therefore, it is
best practice to specify the XQuery version in each module.

The task server does not allow you to specify a default XQuery version, and if there is no explicit
version declaration in the XQuery code evaluated on the task server, the default XQuery version is
determined as follows:

• If you run an xdmp:spawn call, the default XQuery version is 1.0-ml.


• If a trigger action module is executed on the task server (for example, as the result of an
update on a document that has a post-commit update trigger), then the default XQuery
version is the default XQuery version for the App Server that triggered the update (as
specified in the configuration for the App Server).
This makes it especially important to use XQuery version declarations in modules used by CPF or
modules called from triggers. For details on CPF, see the Content Processing Framework Guide.

To ensure your code is always evaluated in the dialect in which you have written it, regardless of
the context in which it is run, the best practice is to begin each XQuery module with a XQuery
version declaration. For the syntax of the version declaration, see “XQuery Version Declaration”
on page 35.

2.5 Specifying the XQuery Dialect in the Prolog


You specify the dialect for an XQuery module with a version declaration. The version declaration
is optional, and comes before the prolog in an XQuery module. It is best practice to put the
XQuery version declaration in your code as the first line in the module, as having it there ensures
it will work as expected in any environment. For example, to specify 1.0-ml as the XQuery
version, begin your XQuery module with the following:

xquery version "1.0-ml";

2.5.1 Porting 0.9-ml XQuery Code to Enhanced 1.0-ml


In most cases, porting any XQuery code used in 0.9-ml to the 1.0-ml dialect will be
straightforward. The bulk of the differences are syntax changes in the prolog. As stated earlier,
you do not need to port all of your code at one time. A sensible approach is to migrate your code
one XQuery module at a time. This section outlines the basic steps to follow when migrating your
XQuery code.

The following are some basic steps to take when migrating 0.9-ml XQuery code to 1.0-ml:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 13


MarkLogic Server XQuery Dialects in MarkLogic Server

1. Add XQuery version declarations to all of your existing modules. For code written in
0.9-ml, the declarations will be as follows:

xquery version "0.9-ml"

Note: If you use the xquery version "0.9-ml" declaration, you will get a warning
message. MarkLogic recommends that you move to either XQuery dialect 1.0-ml
or 1.0 as soon as possible.

2. Review the code for any incompatibilities.

3. For each module you migrate, change the version number string in the XQuery version
declaration to 1.0-ml and add a semi-colon to the line so it appears as follows:

xquery version "1.0-ml";

4. Change all of the prolog declarations to the 1.0 syntax (change define to declare, add
semi-colons, and so on, as described in “XQuery Changes from 0.9-ml to 1.0-ml” on
page 9). For the prolog syntax, see “XQuery Prolog” on page 37, the W3C specification
(http://www.w3.org/TR/xquery/#id-grammar), or a third-party XQuery book.

5. If you are modifying a main module and it has function declarations that are used in the
same module, they must be declared in a namespace. The preferred way to put functions
local to a main module is to prefix those functions definitions and function calls with the
local: prefix, which is predefined.

6. If you have any durations that use the xdt namespace prefix, change the prefix to xs (for
example, change xdt:dayTimeDuration to xs:dayTimeDuration).

7. If you are modifying a library module that is defined with the fn namespace URI, you
must change the namespace URI of that module; you cannot use the URI bound to the fn
namespace prefix as the URI for a library module in 1.0 or 1.0-ml. If you do change the
namespace URI of a library module, you must also change the URI in any import module
statements in other modules that call the library.

8. Test the module and correct any syntax errors that occur.

9. After getting the module to run, test your code to make sure it behaves as it did before. Pay
particular attention to parts of your code that might rely on boolean values that take
boolean values of sequences, as those behave differently in 0.9-ml and 1.0-ml (see
“XQuery Changes from 0.9-ml to 1.0-ml” on page 9). Check for any changes due to
function mapping, which is described in “Function Mapping” on page 17.

10. Repeat this process for other modules you want to migrate.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 14


MarkLogic Server MarkLogic Server Enhanced XQuery Language

3.0 MarkLogic Server Enhanced XQuery Language


31

The default XQuery dialect in MarkLogic Server is enhanced. (1.0-ml) The enhanced dialect
includes all of the features in the strict XQuery 1.0 dialect, and adds several other features to
make it easier to use XQuery as a programming language with which to create applications. This
chapter describes the features of the enhanced dialect and includes the following sections:

• try/catch Expression

• Function Mapping

• Semi-Colon as Transaction Separator

• Private Function and Variable Definitions

• Functions With Side Effects

• Shorthand Positional Predicate Syntax

• Binary Node Constructor and Node Test

• validate as Expression

• Serialization Options

• Importing a Stylesheet Into an XQuery Module

• XQuery 3.x Features

• Implementation-Defined Semantics

For details on the XQuery language, see “XQuery Language” on page 32 and the W3C XQuery
specification (http://www.w3.org/TR/xquery/).

3.1 try/catch Expression


The try/catch extension allows you to catch and handle exceptions. MarkLogic Server exceptions
are thrown in XML format, and you can apply an XPath statement to the exception if there is a
particular part you want to extract. The exception is bound to the variable in the catch clause.

try { expression } catch ( variable ) { expression }

The following code sample uses a try/catch block to catch exceptions upon loading a document,
and prints out the filename if an exception occurs.

try {
let $filename := "/space/myfile.xml"
let $options := <options xmlns="xdmp:document-load">
<uri>/myfile.xml</uri>
<repair>none</repair>
</options>

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 15


MarkLogic Server MarkLogic Server Enhanced XQuery Language

return xdmp:document-load($filename, $options)


}
catch ($exception) {
"Problem loading file, received the following exception: ",
$exception }

Most exceptions can be caught with a try/catch block, but the XDMP-CANCELED, SVC-CANCELED, and
XDMP-DISABLED exceptions cannot be caught in a try/catch block.

When an exception is thrown by code within a try block, all actions taken in that block are rolled
back. If you catch the exception (and do not throw another), then MarkLogic will evaluate
expressions occuring after the try-catch expression.

For example, in the following code, the call to xdmp:document-set-metadata data throws an
XDMP-CONFLICTINGUPDATES exception because it tries to update the document metadata twice in the
same statement. The exception is trapped by the try-catch. The updates in the try block are lost, so
“doc.xml” is not created. The “hello” expression is still evaluated.

xquery version "1.0-ml";


try {
xdmp:document-insert('doc.xml',
<data/>,
map:map() => map:with("metadata",
map:map() => map:with("a", 1)
=> map:with("b",2))
),
xdmp:document-set-metadata('doc.xml', map:map() => map:with("c", 3))
} catch($err) { },
"hello"

(: doc.xml is not inserted; query emits "hello"

By contrast, if you wrap only the call to xdmp:document-set-metadata in the try-catch block, then
the initial document insert still occurs.

xquery version "1.0-ml";


xdmp:document-insert('doc.xml',
<data/>,
map:map() => map:with("metadata",
map:map() => map:with("m", 1)
=> map:with("n",2))
),
try {
xdmp:document-set-metadata('doc.xml', map:map() => map:with("b", 1))
} catch($err) { },
"hello"

(: doc.xml is inserted with m & n metadata keys; query emits "hello" :)

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 16


MarkLogic Server MarkLogic Server Enhanced XQuery Language

Note that Server-Side JavaScript code does not handle JavaScript statements within a try block
the same way as XQuery handles expressions in a try block. In JavaScript, statements in the try
block that complete before the exception occurs are not rolled back if the exception is caught. For
details, see Exception Handling in the JavaScript Reference Guide.

3.2 Function Mapping


Function mapping is an extension to XQuery that allows you to pass a sequence to a function
parameter that is typed to take a singleton item, and it will invoke that function once for each item
in the sequence. This section describes function mapping and includes the following parts:

• Understanding Function Mapping

• Enabling or Disabling Function Mapping

3.2.1 Understanding Function Mapping


Function mapping is equivalent to iterating over the sequence like it was in a for clause of a
FLWOR expression. The following is an example of function mapping:

xquery version "1.0-ml";

declare function local:print-word ($word as xs:string) { $word };

local:print-word( ("hello", "world") )


(:
evaluates the print-word function twice, once for "hello"
and once for "world", returning hello world
:)

Function mapping also works on multiple singleton parameters, resulting in the cross product of
all the values (equivalent to nested for clauses). In the case of multiple mappings, they occur left
to right. For example, the following is evaluated like a nested for loop:

xquery version "1.0-ml";


(1 to 2) * (3 to 4)
(: returns the sequence (3, 4, 6, 8) :)

One consequence of function mapping, which can be surprising the first time you see it, is that if
the value passed for a parameter is the empty sequence, it could result in the function being called
0 times (that is, in the function never runs and results in the empty sequence. For example, if you
entered the empty sequence as the parameter to the above function call, it returns empty, as
follows:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 17


MarkLogic Server MarkLogic Server Enhanced XQuery Language

xquery version "1.0-ml";

declare function local:print-word ($word as xs:string) { $word };

local:print-word( () )
(:
evaluates the print-word function zero times, resulting
in the empty sequence
:)

The local:print-word function is never called in this case, because it is iterating over the empty
sequence, which causes zero invocations of the function. If your function calls are fed by code
that can return the empty sequence (an XPath expression, for example), then you might see this
behavior.

3.2.2 Enabling or Disabling Function Mapping


In 1.0-ml, function mapping is enabled by default. In 1.0, it is disabled by default. You can enable
it in 1.0 by adding the following to the XQuery prolog:

declare namespace xdmp="http://marklogic.com/xdmp";


declare option xdmp:mapping "true";

Similarly, you can explicitly disable function mapping in 1.0-ml by adding the following to the
prolog:

declare option xdmp:mapping "false";

If you run code expecting it to map singletons to a sequence if function mapping is diabled, it will
throw an exception because the sequence cannot be cast to a single string.

Note: If you use item operators on a sequence, in the 1.0-ml dialect they will perform
function mapping, and the value will be the effective boolean value of the
sequence of results. In the 1.0 dialect, they will throw an XDMP-MANYITEMSEQ
exception if you try to compare a sequence of more than one item. For more
details, see Item Operators.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 18


MarkLogic Server MarkLogic Server Enhanced XQuery Language

3.3 Semi-Colon as Transaction Separator


In the enhanced dialect, you can add a semi-colon after one or more XQuery statements in the
body of a main module and then add another one or more XQuery statement. The two sets of
statements are then evaluated as two separate transactions. Each set of statements must be a main
module; that is, they must all have their own prolog elements. All of the statements in the program
must use the same XQuery dialect. For example, the following creates a document and then
returns the contents of the document:

xquery version "1.0-ml";


xdmp:document-insert("/mydocs/sample.xml",
<some-element>content</some-element>) ;

xquery version "1.0-ml";


(: Note that the XQuery version must be the same for all
statements in the module :)
fn:doc("/mydocs/sample.xml")
(: returns the document created in the previous statement :)

Note that you cannot use the semi-colon as a transaction separator in the strict XQuery dialect
(1.0). For more details on transactions, see Understanding Transactions in MarkLogic Server chapter
in the Application Developer’s Guide.

3.4 Private Function and Variable Definitions


In the 1.0-ml enhanced dialect, you can create library modules with functions and variables that
are private to the library module. Private functions and variables are useful when you have certain
code you do not want to expose to users of the library, but might be useful for functions for the
library to use. To make functions and variables private, add private to the function or variable
declaration syntax as follows:

declare private function ....

declare private variable ....

Note that functions and variables in a main module are private by definition, so declaring them
private only makes sense for library modules.

3.5 Functions With Side Effects


The XQuery specification defines that XQuery programs produce only their return values,
without producing any side effects; that is, without causing any changes to the run-time
environment as a result of running the program (with the exception of fn:trace). MarkLogic
Server has many enhancements that cause side effects. For example, there are functions that insert
or update documents in a database. Since functions like the ones that update documents do more
than functions that simply return values, they are extensions to the XQuery specification.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 19


MarkLogic Server MarkLogic Server Enhanced XQuery Language

Side effects are extremely useful when building applications. Therefore, MarkLogic Server
includes many functions that have side effects. The following are some examples of functions
with side effects:

• xdmp:set

• Update Built-ins (xdmp:document-load, xdmp:node-insert, and so on)


• Administrative functions (xdmp:merge, Admin library, xdmp:shutdown, and so on)

3.6 Shorthand Positional Predicate Syntax


MarkLogic Server enhanced mode supports the shorthand version of the positional predicate
syntax, where you can specify the position numbers to include. For example, the following
specifies the first three items in the sequence:

xquery version "1.0-ml";


(1, 2, 3, 4, 5, 5)[1 to 3]

In XQuery 1.0 strict mode (1.0), you must use the fn:position() function as in the following
example:

xquery version "1.0";


(1, 2, 3, 4, 5, 5)[fn:position() = (1 to 3)]

3.7 Binary Node Constructor and Node Test


MarkLogic Server enhanced mode extends the XQuery types to include a binary node type.
Binary nodes are used to store binary documents. To support this type, the MarkLogic Server
enhanced XQuery dialect includes a node constructor (binary) to construct a binary node and a
node test (binary()) to test whether a node is a binary node (for example, in a typeswitch
expression). These extensions are not available in the 1.0 dialect.

3.8 validate as Expression


In the 1.0-ml dialect, you can use the validate as syntax to specify the type for a validate
expression. The validate as expression is an extension to the XQuery 1.0 validate expression,
and it is only available in 1.0-ml; it is not available in the 1.0 dialect. For details on the validate
expression, see “Validate Expression” on page 52.

3.9 Serialization Options


You can set the serialization options in XQuery with the declare option XQuery prolog. In
XSLT, you can set the serialization options using the <xsl:output> instruction. For details on
setting the serialization options in XQuery, see “Declaring Options” on page 38. For XSLT output
details, see the XSLT specification (http://www.w3.org/TR/xslt#output).

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 20


MarkLogic Server MarkLogic Server Enhanced XQuery Language

3.10 Importing a Stylesheet Into an XQuery Module


Using the 1.0-ml dialect, you can import a XSLT stylesheet into an XQuery module, allowing you
access to the functions and variables defined defined by that stylesheet. To import a stylesheet in
XQuery, use a prolog expression of the following form:

import stylesheet at "/path-to-stylesheet.xsl";

The following example shows an XQuery module that imports a stylesheet and runs a function in
the stylesheet:

xquery version "1.0-ml";

(: assumes a stylesheet at /f.xsl with the following contents:


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0" xmlns:foo="foo">
<xsl:function name="foo:foo">foo</xsl:function>
</xsl:stylesheet>
:)

import stylesheet at "/f.xsl";


declare namespace foo="foo";

foo:foo()

(: Returns the string:


foo
which is the output of the
stylesheet function. :)

Similarly, you can import an XQuery module into an XSLT stylesheet, as described in “Importing
XQuery Function Libraries to a Stylesheet” on page 84.

Note: To use functions and variables from a stylesheet in XQuery, define them in a
namespace in the stylesheet. In XQuery, it is difficult to call functions and
variables in no namespace. Therefore, the best practice is, for functions and
variables in a stylesheet that you plan to import into an XQuery module, define
them in a namespace. Note that in an XQuery library module, all function and
variable declarations must be in a namespace.

3.11 XQuery 3.x Features


MarkLogic supports the following subset of language features from XQuery 3.0 and XQuery 3.1.
MarkLogic does not support the entire XQuery 3.0 or 3.1 standard. Unless otherwise noted,
MarkLogic implements the same semantics for these features as described by the XQuery
specification.

• Arrow Operator

• Simple Map Operator

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 21


MarkLogic Server MarkLogic Server Enhanced XQuery Language

• String Concatenation Operator

• URI Qualified Names

• Dynamic Function Invocation

• Inline Functions

• Function Type Testing

• Named Function References

• Partial Function Application

• Function Annotations

• Default Values for External Variables

• Unions in Typeswitch Case Descriptors

• Switch Statement

• Validate Type Expressions

• Error Handling with Try/Catch

3.11.1 Arrow Operator


The arrow operator (“=>”) applies a function to the value of an expression. For example, you can
use the arrow operator to chain together calls to map:with while initializing a map:map:

map:map() => map:with($key1, $value1)


=> map:with($key2, $value2)

In the above example, the map produced by calling map:map or map:with is implicitly the first
param of the applied function (map:with, here).

Without the arrow operator, you would need to make repeated calls to map:put or repeated or
nested calls to map:with, as shown below. The use of the arrow operator can result in more
readable code.

(: using map:put :)
let $map := map:map()
let $_ := map:put($map, $key1, $value1)
let $_ := map:put($map, $key2, $value2)
return $map

(: using map:with :)
map:with(map:with(map:map(), $key1, $value1), $key2, $value2)

For more details, see the discussion of the arrow operator in the XQuery 3.1 specification at
https://www.w3.org/TR/2017/REC-xquery-31-20170321/.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 22


MarkLogic Server MarkLogic Server Enhanced XQuery Language

3.11.2 Simple Map Operator


The simple map operator (“!”) is used in expressions of the following form:

PathExpr1 ! PathExpr2

PathExpr1 is evaluated, and then each item in the resulting sequence acts as the inner focus when
evaluating PathExpr2.

The following example finds all the //child elements of $nodes, and then uses each element as the
context item (“.”) in a call to fn:concat.

xquery version "1.0-ml";


let $nodes := (
<parent><child>a</child></parent>,
<parent><child>b</child></parent>,
<parent><child>c</child></parent>
)
return $nodes//child ! fn:concat("pfx-", .)

(: result: ("pfx-a", "pfx-b", "pfx-c") :)

For more details, see the discussion of the Simple Map Operator in the XQuery 3.0 specification
at https://www.w3.org/TR/xquery-30/#id-map-operator.

3.11.3 String Concatenation Operator


The string concatenation operator (“||”) enables you to concatenate two strings, as if by calling
fn:concat. For example:

"green eggs" || " and " || "ham"

(: result: "green eggs and ham" :)

For more details, see the discussion of String Concatenation Expressions in the XQuery 3.0
specification at https://www.w3.org/TR/xquery-30/#id-string-concat-expr.

3.11.4 URI Qualified Names


A URI Qualified Name enables you to specify a namspace URI literal along with a local name,
instead of pre-defining a namespace prefix. You can use a URI qualified name anywhere you can
use a lexical QName.

A qualifed URI name has the form:

Q{namespaceURI}local_name

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 23


MarkLogic Server MarkLogic Server Enhanced XQuery Language

For example, the element <x:p/> in the following node can be referenced as
Q{http://example.com/ns/foo}p.

xquery version "1.0-ml";


let $node :=
<doc xmlns:x="http://example.com/ns/foo">
<x:p/>
</doc>
return
$node//Q{http://example.com/ns/foo}p

For more details, see the discussion of Expanded QNames in the XQuery 3.0 specification at
https://www.w3.org/TR/xquery-30/#dt-expanded-qname.

3.11.5 Dynamic Function Invocation


This feature enables you to invoke a function through a function reference. For example:

xquery version "1.0-ml";


let $ref := fn:concat#2
return $ref("a","b")

(: returns "ab" :)

For more details, see the discussion of dynamic function calls in the XQuery 3.0 specification at
https://www.w3.org/TR/xquery-30/#id-dynamic-function-invocation.

3.11.6 Inline Functions


Inline functions are defined in the place where you use them, rather than being separately
declared. You can declare a function inline anywhere you can supply a function reference.

The following example passes an inline function as the first parameter of fn:map:

fn:map(function($n) {$n + $n}, (10, 20))

(: returns (20,40) :)

For more details, see the discussion of Inline Function Expressions in the XQuery 3.0
specification at https://www.w3.org/TR/xquery-30/#dt-inline-func.

3.11.7 Function Type Testing


You can use the typed function test feature to test that an expression is a function reference with a
specific signature. The signature you test against can include parameter types and return type.

For more details, see the Function Test in the XQuery 3.0 specification at
https://www.w3.org/TR/xquery-30/#id-function-test.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 24


MarkLogic Server MarkLogic Server Enhanced XQuery Language

3.11.8 Named Function References


You can create a reference to a named function defined in the static context of a query. This
feature enables you to create references to known functions, including distinguishing
implementations that accept a different number of parameters.

For example, the following code creates a reference to the version of the function
local:doSomething that accept two parameters, and then invokes the function through the
reference:

xquery version "1.0-ml";


declare function local:doSomething(
$a as xs:int, $b as xs:int
) as xs:int
{ $a + $b };

declare function local:doSomething(


$a as xs:int, $b as xs:int, $c as xs:int
) as xs:int
{ $a * $b * $c };

let $ref := local:doSomething#2


return $ref(2,3)

You can also create references to functions defined by XQuery and MarkLogic. For example:
fn:concat#3 signifies a reference to fn:concat expecting 3 parameters.

For more details, see the following topic in the XQuery 3.0 specification at
https://www.w3.org/TR/xquery-30/#id-named-function-ref.

3.11.9 Partial Function Application


When creating a function reference, you can fill in specific values for some parameters and use a
placeholder for others. When you make a function call using the reference, you pass in values
only for the placeholder parameters. The other parameters use the explicit values previously
bound to the reference.

For example, the following function reference specifies the value 10 for the first parameter of the
referenced function, and uses a placeholder for the second parameter:

let $fref := local:doSomething(10, ?)

You can invoke the function through the reference and supply only one parameter, which will take
the place of the placeholder parameter. For example:

xquery version "1.0-ml";


declare function local:doSomething(
$a as xs:int, $b as xs:int
) as xs:int

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 25


MarkLogic Server MarkLogic Server Enhanced XQuery Language

{ $a + $b };

let $ref := local:doSomething(10,?)


return $ref(3)

(: returns 13 :)

For more details, see the discussion of partial function application in the XQuery 3.0 specification
at https://www.w3.org/TR/xquery-30/.

3.11.10 Function Annotations


A function annotation declares a property of a function. For example, XQuery defines the
annotations %public and %private for indicating the visibility of a function outside of a module,
such as in the following code snippet:

declare %private my:func($p as xs:int) ...

MarkLogic supports the annotations defined by the XQuery 3.0 specification. MarkLogic also
defines the following implementation-specific annotations:

• %rapi:transaction-mode(mode) : Specify the transaction mode of a function in a REST


Client API extension module. For details, see Controlling Transaction Mode in the REST
Application Developer’s Guide.
For more details, see the discussion of annotations in the Function Declaration topic of the
XQuery 3.0 specification at https://www.w3.org/TR/xquery-30/#FunctionDeclns.

3.11.11 Default Values for External Variables


When you declare an external variable, you can includes a default value in the declaration. If the
dynamic context during query evaluation does not include a value for the variable, the default is
used.

The following example defines an external variable with the default value "my default value".

declare variable $exv as xs:string := "my default value";

For more details, see VarDefaultValue in the Variable Declaration topic of the XQuery 3.0
specification at https://www.w3.org/TR/xquery-30/#id-variable-declarations.

3.11.12 Unions in Typeswitch Case Descriptors


You can use a union of types in the case clause of a typeswitch statement instead of a single type.
The case matches if any of the types in the union match. Use the union operator (“|”) to separate
the types in the clause.

For example, the case clause in the following typeswitch matches either a name or address
element.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 26


MarkLogic Server MarkLogic Server Enhanced XQuery Language

typeswitch($some-node)
case $n as element(name) | element(address) return $n
default return ()

For more details, see the discussion of SequenceTypeUnion in the Typeswitch topic of the
XQuery 3.0 specification at https://www.w3.org/TR/xquery-30/#doc-xquery30-CaseClause.

3.11.13 Switch Statement


A switch statement enables you to choose one of several expressions to evaluate based on value.
By contrast, a typeswitch enable you to choose one of severale expressions based on type.

For example, the following code selects a code path based on the value of a variable.

xquery version "1.0-ml";


let $some-value := 2
return switch($some-value)
case 1 return "one"
case 2 return "two"
default return "many"

(: returns "two" :)

You can use a switch statement that tests the value fn:true() as a “shortcut” for a nested set of
if-then-else expressions. For example:

switch (fn:true)
case ($a > 0) return "positive"
case ($a < 0) return "negative"
default return "zero"

For more details, see the Switch Expression topic in the XQuery 3.0 specification at
https://www.w3.org/TR/xquery-30/#id-switch.

3.11.14 Validate Type Expressions


You can validate a node against in-scope schema definitions using the “validate” operator. You
can specify a validation level (strict or lax) or a specific schema type. This feature is similar to
calling xdmp:validate, except that it raises an error on the first validation failure, rather than
returning a sequence of xdmp:validation-error elements.

The following example specifies a validation level. If you omit the leve, “strict” is implied.

(: validate a structured query :)


xquery version "1.0-ml";
let $query :=
<query xmlns="http://marklogic.com/appservices/search">
<word-query>
<element name="body-color" ns="" />
<text>black</text>
</word-query>

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 27


MarkLogic Server MarkLogic Server Enhanced XQuery Language

</query>
return validate strict { $query }

The following example specifies a type instead:

validate type my:type { $some-node }

For more details, see the discussion of Validate Expressions in the XQuery 3.0 specification at
https://www.w3.org/TR/xquery-30/#id-validate.

3.11.15 Error Handling with Try/Catch


A try/catch expression enables you to trap and handle errors. MarkLogic also supports a
proprietary try/catch implementation, as described in “try/catch Expression” on page 15. You can
use either form.

The MarkLogic-specific and XQuery standard try/catch expressions differ in the following ways:

• In the standard implementation, the catch clause uses a name test to determine whether or
not to trap a given error. This enables you to trap specific exceptions by name. The
proprietary implementation traps any exception.
• The standard implementation pre-defines several variables in the scope of the expression
evaluated in the catch block. These variables provide details about the error. The
proprietary implementation binds an error element to a variable you specify in your catch
clause, and then you access error details through that variable.
You cannot trap MarkLogic errors such as XDMP-AS by name with the standard implementation
because MarkLogic errors do not have QNames. However, you can trap the XQuery standard
error codes or all errors (“*”) with the standard try/catch expression.

The following is an example of an XQuery standard try/catch expression. It traps all all
exceptions and prints out a message constructed from some of the implicitly defined variables.

xquery version "1.0-ml";


try {
fn:error(fn:QName('http://www.w3.org/2005/xqt-errors',
'err:FOER0000'))
}
catch * {
fn:concat($err:code, " at ", $err:line-number, ":",
$err:column-number)
}

For more details, see the Try Catch Expressions discussion in the XQuery 3.0 specification at
https://www.w3.org/TR/xquery-30/#id-try-catch.

3.12 Implementation-Defined Semantics


The XQuery specification lists items that may be defined by each implementation of XQuery:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 28


MarkLogic Server MarkLogic Server Enhanced XQuery Language

http://www.w3.org/TR/xquery/#id-impl-defined-items

This section describes the following implementation-defined items as they are implemented in
MarkLogic Server:

• Automatic Namespace Imports for Predefined Namespaces

• Namespace path

• External Variables

• Collations

• Implementation-Defined Primitive XQuery Types

• Decimal Precision at Least 18 Digits, and is Not Configurable

• Library Modules Default Function Namespace Defaults to Library Namespace

Note: Except where noted, the items in this section apply all of the XQuery dialects
supported in MarkLogic Server.

3.12.1 Automatic Namespace Imports for Predefined Namespaces


Each dialect has a set of namespace prefixes that are predefined. For those predefined
namespaces, it is not necessary to declare the prefix. For example, the fn prefix is predefined in all
of the dialects. For a list of predefined namespaces for each dialect, see “Predefined Namespace
Prefixes for Each Dialect” on page 79.

Note: The fn: prefix is bound to a different namespace in 1.0 and 1.0-ml than in 0.9-ml.

3.12.2 Namespace path


The namespace path is a list of namespace URIs. Any namespaces listed in a using namespace
prolog declaration are added to a namespace path. When resolving any function call that doesn’t
use a prefix, the namespaces in the namespace path are used in turn.

For example, the following code adds http://marklogic.com/xdmp to the namespace path:

using namespace "http://marklogic.com/xdmp";

3.12.3 External Variables


External variables are one of the things that the XQuery standard refers to as
implementation-defined. In MarkLogic Server, external variables are implemented such that you
can pass nodes and values into an XQuery program. To use external variables, you pass in
external variables to the XQuery program (via xdmp:invoke, xdmp:eval, xdmp:spawn, or via XCC).
The variables are passed in as pairs of QNames and values.

An XQuery program that accepts external variables must declare the external variables in its
prolog, as in the following code snippet:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 29


MarkLogic Server MarkLogic Server Enhanced XQuery Language

declare variable $my:variable as xs:string* external;

You can create a default value for the variable by adding the := to the specification, as in the
following code snippet:

declare variable $my:variable as xs:string* external


:= "default value";

An XQuery program with this variable declaration would be able to use the string values passed
into it via an external variable with the QName my:variable (where the namespace prefix my was
declared somewhere in both the calling and called environments). You could then reference this
variable in the XQuery program as in the following example:

xquery version "1.0-ml";


declare namespace my="myNamespace";
declare variable $my:variable as xs:string* external;

fn:concat("The value of $my:variable is: ", $my:variable)

If you then call this module as follows (assuming the module can be resolved from the path
/extvar.xqy.

xquery version "1.0-ml";


declare namespace my="myNamespace";

xdmp:invoke("/extvar.xqy", (xs:QName("my:variable"), "my value"))

This example returns the following string:

The value of $my:variable is: my value

Note: MarkLogic Server will not accept more than 1024 external variable value items
over XDBC.

3.12.4 Collations
The XQuery specification allows collation names and default collation values to be determined by
the implementation. MarkLogic Server uses collations to specify the sort order of strings, and it
defines the URIs for the collations. Each query runs with a default collation, and that collation can
come from the environment (each App Server has a default collation setting) or it can be specified
in the XQuery program. Also, you can specify collations for string range indexes and for word
lexicons to specify their sort order. For details about collations in MarkLogic Server, including
the valid URIs for collations, see Encodings and Collations in the Search Developer’s Guide.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 30


MarkLogic Server MarkLogic Server Enhanced XQuery Language

3.12.5 Implementation-Defined Primitive XQuery Types


MarkLogic Server has extended the XQuery type system and added some primitive types. These
types allow functions to operate on them and are very useful for programming. These types are
not required by the XQuery specification, but neither are they in conflict with it because the
specification allows implementation-specific primitive types. Therefore, these types are available
in all of the XQuery dialects in MarkLogic Server (although in 1.0, you need to import the
namespace prefixes). The following are some of the built-in types in MarkLogic Server:

• cts:query (with many subtypes such as cts:word-query, cts:element-query, and so on)


• map:map

• cts:region (with subtypes cts:box, cts:circle, cts:polygon, and cts:point)


• json:object
• json:array

3.12.6 Decimal Precision at Least 18 Digits, and is Not Configurable


MarkLogic Server does not include a facility to limit the maximum precision of a decimal. A
decimal has a precision of at least 18 decimal digits (64-bits unsigned). For details, see the XML
Schema specification (http://www.w3.org/TR/xmlschema-2/#decimal).

3.12.7 Library Modules Default Function Namespace Defaults to Library


Namespace
The default function namespace of an XQuery library module is the namespace of the library
module. This allows you to declare functions in the library namespace without prefixing the
functions. You can override the default function namespace with a declare default function
namespace declaration in the prolog of the library module. For library modules where you do not
override the default function namespace (and as a general best-practice), prefix the
XQuery-standard functions (functions with the fn: prefix, which is bound to the
http://www.w3.org/2005/xpath-functions namespace) with the fn: prefix. Note that main
modules default function namespace defaults to the fn: namespace, which is different from
library modules.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 31


MarkLogic Server XQuery Language

4.0 XQuery Language


56

The chapter describes selected parts of the XQuery language. It is not a complete language
reference, but it touches on many of the widely used language constructs. For complete details on
the language and complete syntax for the language, see the W3C XQuery specification
(http://www.w3.org/TR/xquery/). Additionally, there are many third-party books available on the
XQuery language which can help with the basics of the language. This chapter has the following
sections:

• Expressions Return Items

• XML and XQuery

• JSON and XQuery

• XQuery Modules

• XQuery Prolog

• XQuery Comments

• XQuery Expressions

• XQuery Comparison Operators

Note: This chapter describes a subset of the XQuery 1.0 recommendation syntax, which
is used in the 1.0 and 1.0-ml dialects. For an overview of the different XQuery
dialects, see “XQuery Dialects in MarkLogic Server” on page 7.

4.1 Expressions Return Items


The fundamental building block in XQuery is the XQuery expression, which is what the XQuery
specification refers to as one or more ExprSingle expressions. Each XQuery expression returns a
sequence of items; that is, it returns zero or more items, each of which can be anything returned
by XQuery (for example, a string, a node, a numeric value, and so on).

Any valid XQuery expression is a valid XQuery. For example, the following is a valid XQuery:

"Hello World"

It returns the string Hello World. It is a simple string literal, and is a valid XQuery. You can
combine expressions together using the concatenation operator, which is a comma ( , ), as
follows:

"Hello", "World"

This expression also returns a sequnce of two string Hello and World. It is two expressions, each
returning a single item (therefore it returns a sequence of two strings). In some contexts (a
browser, for example), the two strings will be concatenated together into the string Hello World.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 32


MarkLogic Server XQuery Language

Expressions can also return no items (the empty sequence), or they can return sequences of items.
The following adds a third expression:

"Hello", "World", 1 to 10

This expression returns the sequence Hello World 1 2 3 4 5 6 7 8 9 10, where the sequence
1 to 10 is a sequence of numeric values. You can create arbitrarily complex expressions in
XQuery, and they will always return zero or more items.

4.2 XML and XQuery


XQuery is designed for working with XML, and there are several ways to construct and return
XML from XQuery expressions. This section describes some of the basic ways to combine XML
and XQuery, and contains the following parts:

• Direct Element Constructors: Switching Between XQuery and XML Using Curly Braces

• Computed Element and Attribute Constructors

• Returning XML From an XQuery Program

4.2.1 Direct Element Constructors: Switching Between XQuery and XML


Using Curly Braces
As described in the previous section, an XQuery expression by itself is a valid XQuery program.
You can create XML nodes as XQuery expressions. Therefore, the following is valid XQuery:

<my-element>content goes here</my-element>

It simply returns the element. The XQuery syntax also allows you to embed XQuery between
XML, effectively “switching” back and forth between an XML syntax and an XQuery syntax to
populate parts of the XML content. The separator characters to “switch” back and forth between
XML and XQuery are the open curly brace ( { ) and close curly brace ( } ) characters. For
example, consider the following XQuery:

<my-element>{fn:current-date()}</my-element>

This expression returns an XML element named my-element with content that is the result of
evaluating the expression between the curly braces. This expression returns the current date, so
you get an element that looks like the following:

<my-element>2008-06-25-07:00</my-element>

You can create complex expressions that go “back and forth” between XML and XQuery as often
as is needed. For example, the following is slightly more complex:

<my-element id="{xdmp:random()}">{fn:current-date()}</my-element>

This returns an element like the following:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 33


MarkLogic Server XQuery Language

<my-element id="9175848626240925436">2008-06-25-07:00</my-element>

This technique of constructing XML are called direct element constructors. There are many more
rules for how to use these direct element constructors to create XML nodes. For more details, see
the of the XQuery specification (http://www.w3.org/TR/xquery/#doc-xquery-DirCommentConstructor).

4.2.2 Computed Element and Attribute Constructors


You can also create XML nodes by using computed constructors. There are computed
constructors for all types of XML nodes (element, attribute, document, text, comment, and
processing instruction). The following is the basic syntax for computed constructors:

element { xquery-expr }

attribute QName

document

text { xquery-expr }

comment
{ xquery-expr }
processing-instruction
NCName

The following is an example of some XML that is created using computed constructors:

element hello { attribute myatt { "world" } , "hello world" }


(:
returns the following XML:
<hello myatt="world">hello world</hello>
:)

In this example, the comma operator concatenates a constructed attribute (the myatt attribute on
the hello element) and a literal expression (hello world, which becomes the element text node
content) to create the content for the element node. The following example shows how you can
compute the QName with an XQuery expression:

element {xs:QName("hello")} {
attribute myatt { "world" } , "hello world" }
(:
returns the following XML:
<hello myatt="world">hello world</hello>
:)

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 34


MarkLogic Server XQuery Language

4.2.3 Returning XML From an XQuery Program


Using the direct and computed constructors described above, it is natural to have the output of an
XQuery program be XML. Besides computed and direct constructors, XML can be the result of
an XPath expression, a cts:search expression, or any other expression that returns XML. The
XML can be constructed as any well-formed XML.

When you construct XML in XQuery, the XQuery evaluator will always construct well-formed
XML (assuming your XQuery is valid). Compared with other languages where you construct
strings that represent XML, the fact that the XQuery rules ensure that an XML node is well
formed tends to eliminate a whole class of bugs in your code that you might encounter using other
languages.

4.3 JSON and XQuery


You can construct JSON nodes using computed constructors, just as you can create XML nodes.
The MarkLogic API includes constructors for JSON nodes such as objects, arrays, numbers, and
booleans. You can also construct JSON documents from a serialized string representation, using
xdmp:unquote. For details, see Constructing JSON Nodes in the Application Developer’s Guide.

4.4 XQuery Modules


While expressions are the building blocks of XQuery coding, modules are the building blocks of
XQuery programs. There are two kinds of XQuery modules: main modules and library modules.
This section describes XQuery modules and includes the following sections:

• XQuery Version Declaration

• Main Modules

• Library Modules

This section provides some basic syntax for XQuery modules. For the complete syntax of XQuery
modules, see the XQuery specification (http://www.w3.org/TR/xquery/#doc-xquery-Module).

4.4.1 XQuery Version Declaration


Every XQuery module (both main and library) can have an optional XQuery version declaration.
The version declaration tells MarkLogic Server which dialect of XQuery to use. MarkLogic
Server supports the following values for the XQuery version declaration: 1.0-ml, 1.0, and 0.9-ml.

Note: XQuery dialect 0.9-ml has been deprecated. MarkLogic recommends that you use
either 1.0-ml or 1.0.

For details on dialects 1.0 and 1.0-ml, including rules for the combining different dialects, see
“XQuery Dialects in MarkLogic Server” on page 7.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 35


MarkLogic Server XQuery Language

The following is the basic syntax of the XQuery version declaration:

"1.0-ml" ;

xquery version "1.0" ;

"0.9-ml"

The following is an example of an XQuery version declaration:

xquery version "1.0-ml";

4.4.2 Main Modules


A main module contains an XQuery program to be evaluated. You can call a main module
directly and it will return the results of the evaluation. A main module contains an optional
XQuery version declaration, a prolog (the prolog can be empty, so it is in effect optional), and a
body. The XQuery body can be any XQuery expression.

In 1.0-ml, you can construct programs that have multiple main modules separated by semi-colons,
as described in “Semi-Colon as Transaction Separator” on page 19.

The following is an example of a very simple main module:

xquery version "1.0-ml";


"hello world"

For another example of a main module, see the example at the end of the “Library Modules” on
page 36.

4.4.3 Library Modules


A library module contains function definitions and/or variable definitions. You cannot call a
library module to directly evaluate it, and it cannot have a query body. To use a library module, it
must be imported from another module (main or library). A library module contains a module
declaration followed by a prolog. For details on the prolog, see “XQuery Prolog” on page 37. The
following is the basic syntax of a library module:

module namespace NCName = URILiteral ;

XQuery prolog

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 36


MarkLogic Server XQuery Language

The following is a very simple XQuery library module

xquery version "1.0-ml";


module namespace my-library="my.library.uri" ;

declare function hello() { "hello" };

If you stored this module under an App Server root as hello.xqy, you could call this function with
the following very simple main module:

xquery version "1.0-ml";


import module namespace my-library="my.library.uri" at "hello.xqy";

my-library:hello()
(: this returns the string "hello" :)

4.5 XQuery Prolog


The XQuery prolog contains any module imports, namespace declarations, function definitions,
and variable definitions for a module. You can have a prolog in either a main module or a library
module. The prolog is optional, as you can write an XQuery program with no prolog. This section
briefly describes the following parts of the XQuery prolog:

• Importing Modules or Schemas

• Declaring Namespaces

• Declaring Options

• Declaring Functions

• Declaring Variables

• Declaring a Default Collation

4.5.1 Importing Modules or Schemas


You can import modules and schemas in the XQuery prolog. The following are sample module
and schema import declarations:

import module namespace my-library="my.library.uri" at "hello.xqy";

import schema namespace xhtml="http://www.w3.org/1999/xhtml"


at "xhtml1.1.xsd";

The library module location and the schema location are not technically required. The location
must be supplied for module imports, however, as they are used to determine the location of the
library module and the module will not be found without it. Also, all modules for a given
namespace must be imported with a single import statement (with comma-separated locations).
For schema imports, if the location is not supplied, MarkLogic Server resolves the schema URI
using the in-scope schemas (schemas in the schemas database and the <marklogic-dir>/Config

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 37


MarkLogic Server XQuery Language

directory). If there are multiple schemas with the same URI, MarkLogic Server chooses one of
them. Therefore, to ensure you are importing the correct schema, use the location for the schema
import, too. For details on the rules for resolving the locations, see Importing XQuery Modules, XSLT
Stylesheets, and Resolving Paths in the Application Developer’s Guide.

For more details on imports, see the XQuery specification for schema imports
(http://www.w3.org/TR/xquery/#id-schema-import) and for module imports
(http://www.w3.org/TR/xquery/#id-module-import).

4.5.2 Declaring Namespaces


Namespace declarations are used to bind a namespace prefix to a namespace URI. The following
is a sample namespace declaration:

declare namespace my-namespace="my.namespace.uri";

For more details on namespace declarations, see the XQuery specification


(http://www.w3.org/TR/xquery/#id-namespace-declaration)

4.5.3 Declaring Options


XQuery provides vendor-specific options that are declared in the prolog. This section describes
the MarkLogic Server options you can declare in the XQuery prolog, and includes the following
prolog options:

• xdmp:mapping

• xdmp:update

• xdmp:commit

• xdmp:transaction-mode

• xdmp:copy-on-validate

• xdmp:output

• xdmp:coordinate-system

4.5.3.1 xdmp:mapping
declare option xdmp:mapping "false";

The xdmp:mapping option sets whether function mapping is enabled in a module. For details on
function mapping, see “Function Mapping” on page 17.

4.5.3.2 xdmp:update
declare option xdmp:update "true";

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 38


MarkLogic Server XQuery Language

The xdmp:update option forces a request to either be an update ("true"), a query ("false"), or to
determine the update mode of the query at compile time ("auto"). Without this option, the request
will behave as if the option is set to "auto" and determine at compile time whether to run as an
update statement (in readers/writers mode) or whether to run at a timestamp. For details on update
statements versus query statements, see Understanding Transactions in MarkLogic Server in the
Application Developer’s Guide.

4.5.3.3 xdmp:commit
declare option xdmp:commit "explicit";

The xdmp:commit option specifies whether MarkLogic treats each XQuery statement as a
single-statement, auto-commit transaction ("auto") or a multi-statement transaction that must be
explicitly commited or rolled back ("explicit"). The default behavior is auto.

For more details, see Understanding Transactions in MarkLogic Server in the Application Developer’s
Guide.

4.5.3.4 xdmp:transaction-mode

Note: This option is deprecated. Use xdmp:update and xdmp:commit, instead.

Use xdmp:transaction-mode to change the runtime model for newly created transactions. The
transaction mode affects when transactions are created, whether or not they span statement
boundaries, and when and how they are committed. The default mode is auto:

declare option xdmp:transaction-mode "auto";

You can specify the following values for xdmp:transaction-mode, as string literals:

• auto (default)
• update-auto-commit

• update

• query

• query-single-statement

• multi-auto

These values correspond to the equivalent settings for the xdmp:set-transaction-mode XQuery
function. Use the option, rather than the API function, if you need to set the transaction mode
before creating any transactions.

For details on transaction modes, see Transaction Mode in the Application Developer’s Guide, and
the discussion of xdmp:set-transaction-mode in MarkLogic XQuery and XSLT Function
Reference.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 39


MarkLogic Server XQuery Language

4.5.3.5 xdmp:copy-on-validate
declare option xdmp:copy-on-validate "true";

The xdmp:copy-on-validate option defines the behavior of the validate expression. You can set
the option to make a copy of the node during schema validation. For details, see “Validate
Expression” on page 52.

4.5.3.6 xdmp:output
The xdmp:output option determines how the output is serialized. The options mirror the
serialization options for xslt using the <xsl:output> XSLT instruction. The following example
causes html serialization:

declare option xdmp:output "method = html";

For details on the <xsl:output> XSLT instruction, from which many of the xdmp:output options
are derived, see http://www.w3.org/TR/xslt#output in the XSLT specification. You can combine
options by having multiple declare option statements.

Valid values for the xdmp:output option are (the values must be string literals):

• method = xml
• method = html
• method = text
• method = sparql-results-json
• method = n-triples
• method = n-quads
• method = sparql-results-csv
• method = rows-json
• method = rows-json-seq
• method = rows-json-multipart
• method = rows-xml
• method = rows-xml-multipart
• method = rows-json-uniform
• method = rows-json-seq-uniform
• method = rows-json-multipart-uniform
• method = rows-xml-uniform
• method = rows-xml-multipart-uniform
• method = rows-json-multipart-node
• method = rows-json-multipart-uniform-node
• method = rows-xml-multipart-node
• method = rows-xml-multipart-uniform-node
• cdata-section-elements = <QName>

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 40


MarkLogic Server XQuery Language

• where <QName> is a list of QNames to output as CDATA elements


• encoding = <encoding>
• use-character-maps=xdmp:sgml-entities-normal
• use-character-maps=xdmp:sgml-entities-math
• use-character-maps=xdmp:sgml-entities-pub
• media-type = <media>
• media-type = text/plain
• media-type = text/xml

• and so on with other valid mimetypes...


• byte-order-mark = yes
• byte-order-mark = no
• indent = yes
• indent = no
• indent-untyped = yes
• indent-untyped = no
• indent-tabs = yes
• indent-tabs = no
• include-content-type = yes
• include-content-type = no
• escape-uri-attributes = yes
• escape-uri-attributes = no
• doctype-public = <publicid1>

• where <publicid1> is the public identifier to use on the emitted DOCTYPE


• doctype-system = <systemid1>

• where <systemid1> is the system identifier to use on the emitted DOCTYPE


• omit-xml-declaration = no
• omit-xml-declaration = yes
• standalone = yes
• standalone = no
• normalization-form = NFC
• normalization-form = NFD
• normalization-form = NFKD
• default-attributes = no
• default-attributes = yes

Additionally, these are all available in XSLT as attributes on the <xsl:output> instruction. In the
<xsl:output> instruction, use these attributes in the form:

attribute-name="value"

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 41


MarkLogic Server XQuery Language

The exceptions to this are the MarkLogic extensions indent-untyped and default-attributes.
When using these attributes, use the namespace prefix xdmp with the attributes (and you must
define the prefix in your stylesheet XML). For example:

<xsl:output xdmp:default-attributes="no" xdmp:intent-untyped="yes"


xmlns:xdmp="http://marklogic.com/xdmp"/>

4.5.3.7 xdmp:coordinate-system
Use xdmp:coordinate-system to override the App Server default geospatial coordinate system and
precision. For example, the following declaration specifies that a module will use the “wgs84”
coordinate system and double precision in geospatial operations.

declare option xdmp:coordinate-system "wgs84/double";

The coordinate system name can be any of the canonical names generated by
geo:coordinate-system-canonical, including the following:

• wgs84
• wgs84/double
• raw
• raw/double
Single precision is implied where the name does not explicitly include “double”.

4.5.4 Declaring Functions


Functions are a fundamental part of programming in XQuery. Functions provide more than a
mechanism to modularize your code (although they certainly are that), as functions allow you to
easily perform recursive actions. This is a powerful design pattern in XQuery.

Functions can optionally be typed, both for parmeters to the function and for results of the
function. The following is a very simple function declaration that takes a string as input and
returns a sentence indicating the length of the string:

declare function simple($input as xs:string) as xs:string* {


fn:concat('The string "', $input, '" is ',
(fn:string-length($input)),
' characters in length.')
} ;

4.5.5 Declaring Variables


You can declare variables in a main or library module to reference elsewhere in your programs. If
you put variable definitions in a library module, you can reference those variables from any
module that imports the library module. Because the content of a variable can be any valid
XQuery expression, you can create variables with dynamic content. The following is a variable
declaration that returns a string indicating if it is January or not:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 42


MarkLogic Server XQuery Language

declare variable $is-it-january as xs:string :=


if ( fn:month-from-date(fn:current-date()) eq 1 )
then "it is January"
else "it is not January" ;

If this variable were defined in a library module named mylib.xqy stored under your App Server
root, and if you imported that library module bound to the namespace prefix mylib into a main
module, then you can reference this variable in the main module as follows:

xquery version "1.0-ml";


import module namespace mylib="my.library.uri" at "mylib.xqy";

$mylib:is-it-january

4.5.6 Declaring a Default Collation


The default collation declaration defines the collation that is in effect for a query. In general,
everything that uses a collation in a query with a default collation declaration will use the
collation specified. The exceptions are for functions that have options which explicitly override
the default collation, and for FLWOR expressions that explicitly state the collation in the order by
clause. The following is a sample collation declaration:

declare default collation "http://marklogic.com/collation/";

For more details on collations, see the Encodings and Collations chapter of the Application
Developer’s Guide.

4.6 XQuery Comments


You can add comments throughout an XQuery program. Comments are surrounded by “smiley
face” symbols. The open parenthesis followed by the colon characters ( (: ) denote the start of a
comment, and the colon followed by a close parenthesis characters ( (: ) denote the end of a
comment. Comments can be nested within comments, which is useful when cutting and pasting
code with comments in it into a comment. The following is an example of an XQuery that starts
with a comment:

(: everything between the smiley faces is a comment :)


"some XQuery goes here"

Note: You cannot put a comment inside of a text literal or inside of element content. For
example, the following is not interpreted as having a comment:

<node>(: not a comment :)</node>

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 43


MarkLogic Server XQuery Language

4.7 XQuery Expressions


This section describes the following XQuery expressions:

• XPath Expressions

• FLWOR Expressions

• The typeswitch Expression

• The if Expression

• Quantified Expressions (some/every ... satisfies ...)

• Validate Expression

4.7.1 XPath Expressions


XPath expressions search for XML content. They can be combined with other XQuery
expressions to form other arbitrarily complex expressions. For more details on XPath expressions,
see “XPath Quick Reference” on page 57.

4.7.2 FLWOR Expressions


The FLWOR expression (for, let, where, order by, return) is used to generate items or
sequences. A FLWOR expression binds variables, applies a predicate, orders the data set, and
constructs a new result:

The following is the basic syntax of a FLWOR expression:

for clause
return clause
let clause
where clause order by clause

The following sections examine each of the five clauses in more detail:

• The for Clause

• The let Clause

• The where Clause

• The order by Clause

• The return Clause

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 44


MarkLogic Server XQuery Language

4.7.2.1 The for Clause


The for clause is used for iterating over one or more sequences:

for $variable in expression

as type at iterator

The for clause iterates over each item in the expression to which the variable is bound. In the
return clause, an action is typically performed on each item in the variable bound to the
expression. For example, the following binds a sequence of integers to a variable and then
performs an action (multiplies it by 2) on each item in the sequence:

for $x in (1, 2, 3, 4, 5)
return
$x * 2

(: returns the sequence (2, 4, 6, 8, 10) :)

As is common in XQuery, order is significant, and the items are bound to the variable in the order
they are output from the expression.

You can also bind multiple variables in one or more for clauses. The FLWOR expression then
iterates over each item in the subsequent variables once for each item in the first variable. For
example:

for $x in (1,2,3)
for $y in (4,5,6)
return
$x * 2

(: returns the sequence (2, 2, 2, 4, 4, 4, 6, 6, 6) :)

In this case, the inner for loop (with $y) is executed one complete iteration for each of the items in
the outer for loop (the one with $x). Even though it does not return anything from $y, the
expression in the return clause is evaluated once for each item in $y, and that happens once for
each item in $x.

You could return something from each iteration of $y, as in the following example:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 45


MarkLogic Server XQuery Language

for $x in (1,2,3)
for $y in (4,5,6)
return
($x * 2, $y * 3)

(: returns the sequence


(2, 12, 2, 15, 2, 18, 4, 12, 4, 15, 4, 18, 6, 12, 6, 15, 6, 18) :)

Alternately, you could write the two for clauses as follows, with the same results:

for $x in (1,2,3), $y in (4,5,6)

When you have multiple variables bound in for clauses, it is an effective way of joining content
from one variable with the other. Note that if the content from each variable comes from a
different document, then multiple for clauses in a FLOWR expression ends up performing a join
of the documents.

4.7.2.2 The let Clause


The let clause is used for binding variables (without iteration) to a single value or to sequences of
values:

let $variable := expression

as type

A let clause produces a single binding for each variable. Consequently, let clauses do not affect
the number of binding tuples evaluated in a FLWOR expression. Variables bound in a let clause
are available to anything that follows in the FLWOR expression (for example, subsequent for or
let clauses, the where clause, the order by clause, or the return clause).

In its simplest form, the let clause allows you to build a FLWOR expression that outputs the
sequence to which the variable is bound. For example, the following expression:

let $seq := ("hello", "goodbye") return $seq

is equivalent to the following expression:

"hello", "goodbye"

They each return the two item sequence hello goodbye.

A typical use for a let clause is to bind a sequence to a variable, then use the variable in a for
clause to iterate over each item. For example:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 46


MarkLogic Server XQuery Language

let $x := (1 to 5)
for $y in $x
return
$x * 2

(: returns the sequence (2, 4, 6, 8, 10) :)

Again, this is a trivial example, but it could be that the expression in the let binding is
complicated, and this technique allows you to cleanly structure your code.

4.7.2.3 The where Clause


The where clause specifies a filter condition on the tuples emerging from the for-let portion of a
FLWOR expression:

where boolean-expression

Only tuples for which the boolean-expression evaluates to true will contribute to the result sequence
of the FLWOR expression The where clause preserves the order of tuples, if any. boolean-expression
may contain and, or and not, among other operators.

Typically, you use comparison operators to test for some condition in a where clause. For
example, if you only want to output from the FLWOR items that start with the letter “a”, you can
do something like the following:

for $x in ("a", "B", "c", "A", "apple")


where fn:starts-with(fn:lower-case($x), "a")
return
$x

(: returns the sequence ("a", "A", "apple") :)

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 47


MarkLogic Server XQuery Language

4.7.2.4 The order by Clause


The order by clause specifies the order (ascending or descending) to sort items returned from a
FLWOR expression, and also provides an option to specify a collation URI with which to
determine the order:

order by $varExpr

stable ascending

descending

empty greatest collation uri

empty least

The order by clause can be used to specify an order in which the tuple sequence will be passed to
the return clause. The order by clause can specify any sort key, regardless of whether that sort
key is contained in the result sequence. You can reorder sequences on an ascending or descending
basis.

The following example sorts the sequence bound to $x (in collation order) by each item:

for $x in ( "B", "c", "a", "d")


order by $x
return $x (: returns the sequence ("a", "B", "c", "d") :)

The following example specifies multiple sort keys:

xquery version "1.0-ml";


for $x in ( <data><a>1</a><b>10</b></data>,
<data><a>20</a><b>5</b></data>,
<data><a>20</a><b>25</b></data> )
order by $x/a descending, $x/b
return $x

(: returns the following sequence


: <data><a>20</a><b>25</b></data>
: <data><a>20</a><b>5</b></data>
: <data><a>1</a><b>10</b></data>
:)

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 48


MarkLogic Server XQuery Language

4.7.2.5 The return Clause


The return clause constructs the result of a FLWOR expression:

return expression

The return expression is evaluated once for each tuple of bound variables. This evaluation
preserves the order of tuples, if any, or it can impose a new order using the order by clause.

Because the return clause specifies an expression, any legal XQuery expression can be used to
construct the result, including another FLWOR expression.

4.7.3 The typeswitch Expression


The typeswitch expression allows conditional evaluation of a set of sub-expressions based on the
type of a specified expression:

typeswitch ( expression )

case sequenceType return case_expr_n

variable as

default return expr_default

variable

A typeswitch expression evaluates the first case_expr whose sequenceType matches the type of
the specified expression. If there is no sequenceType match, expr_default is evaluated.

Typeswitch provides a powerful mechanism for processing node contents:

typeswitch ($address)
case $a as element(*, USAddress) return handleUS($a)
case $a as element(*, CanadaAddress) return handleCanada($a)
default return handleUnknown($address)

This code snippet determines the sequenceType of the variable $address, then evaluates one of
three sub-expressions. In this case:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 49


MarkLogic Server XQuery Language

• If $address is of type USAddress, the function handleUS($a) is evaluated.


• If $address is of type CanadaAddress, the function handleCanada($a) is evaluated.
• If the type of variable $address matches none of the above, the function
handleUnknown($a) is evaluated.

A sequenceType can also be a kind test (such as an element test). It is possible to construct case
clauses in which a particular expression matches multiple sequenceTypes. In this case, the
case_expr of only the first matching sequenceType is evaluated. You can also use the typeswitch
expression in a recursive function to iterate through a document and perform transformation of
the document. For details about using recursive typeswitches, see the Transforming XML Structures
With a Recursive typeswitch Expression chapter of the Application Developer’s Guide.

4.7.4 The if Expression


The if expression allows conditional evaluation of sub-expressions:

if ( expr_c1 ) then expr_r1 else expr_r2

If expression expr_c1 evaluates to true, then the value of the if expression is the value of
expression expr_r1, otherwise the value of the if expression is the value of expr_r2. The else
clause is not optional; if no action is to be taken, use an empty sequence for expr_r2; there is no
“end if” or similar construct in XQuery:

if (1 eq 2)
then "this is strange"
else ()

The extent of expr_r1 and expr_r2 is limited to a single expression. If a more complex set of
actions are required, an element constructor, sequence, or function call must be used.

If expressions can be nested:

if ($year < 1994)


then
<available>archive</available>
else if ($year = $current_year) then
<available>current</available>
else
<available>inventory</available>

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 50


MarkLogic Server XQuery Language

4.7.5 Quantified Expressions (some/every ... satisfies ...)


XQuery provides predicates that simplify the evaluation of quantified expressions. The basic
syntax for these expressions follows:

some var in expr satisfies predicate

every var in expr satisfies predicate

These expressions are particularly useful when trying to select a node based on a condition
satisfied by at least one or alternatively all of a particular set of its children.

Imagine an XML document containing log messages. The document has the following structure:

<log>
<event>
<program> .... </program>
<message> .... </message>
<level> .... </level>
<error>
<code> .... </code>
<severity> .... </severity>
<resolved> .... </resolved>
</error>
<error>
....
</error>
....
</event>
....
</log>

Every <event> node has <program>, <message>, and <level> children. Some <event> nodes have
one or more <error> children.

Consider a query to report on those events that have unresolved errors:

for $event in /log/event


where some $error in $event/error satisfies $error/resolved = "false"
return
$event

This query returns only those <event> nodes in which there is an <error> node with a <resolved>
element whose value is “false”.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 51


MarkLogic Server XQuery Language

4.7.6 Validate Expression


The validate expression is used to validate element and document nodes against in-scope schemas
(schemas that are in the schemas database). The following is the basic syntax of the validate
expression:

validate { expr }
lax
strict
as XML_type

The expression to validate must be a node referencing an in-scope schema. The node can
reference a schema. The default validation mode is strict. When performing lax validation, the
validate expression first tries to validate the node using an in-scope schema, and then if no schema
is found and none is referenced in the node, the validation occurs without a schema. If a node is
not valid, an exception is thrown. If a node is valid, then the node is returned. For more details,
see the XQuery specification (http://www.w3.org/TR/xquery/#id-validate).

You can also set a prolog option to determine if the node returned is a copy of the original node
(losing its context) or the original node (keeping its context). The XQuery specification calls for
the node to be a copy, but it is often useful for the node to retain its original context (for example,
so you can look at its ancestor elements). The following is the prolog option:

declare option xdmp:copy-on-validate "true";

You can specify true or false. This option is true by default in the 1.0 dialect, and false by
default in the 1.0-ml dialect.

The following is a simple validate expression:

xquery version "1.0-ml";


validate { <p xmlns="http://www.w3.org/1999/xhtml">hello there</p> }

(:
validates against the in-scope xhtml schema and returns the element:
<p xmlns="http://www.w3.org/1999/xhtml">hello there</p>
:)

The as XML_type validation mode allows you to specify the type to validate as (rather than use the
in-scope schema definitions for the type). This mode is an extension to the XQuery 1.0 syntax and
is only available in the 1.0-ml dialect.

xquery version "1.0-ml";

validate as xs:boolean { <foo>{fn:true()}</foo> }

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 52


MarkLogic Server XQuery Language

In the 1.0 dialect (or also in the 1.0-ml dialect), you can specify the an xdmp:validate-type
pragma before an expression to perform the same as XML_type validation, but without the
validate as syntax, as in the following example:

xquery version "1.0";


declare namespace xdmp="http://marklogic.com/xdmp";

(# xdmp:validate-type xs:boolean #) { <foo>{fn:true()}</foo> }

4.8 XQuery Comparison Operators


This section lists the comparison operators in XQuery. The purpose of the operators are to
compare expressions. This section includes the following parts:

• Node Comparison Operators

• Sequence and Item Operators

4.8.1 Node Comparison Operators


You can specify node comparisons to test if two nodes are before or after each other (in document
order), or if the nodes are the exact same node. These tests return true or false. The following are
the node comparison operators:

Operator Description Example

<< The node before let $x := <foo>


operator. Tests if a <bar>hello</bar>
<baz>goodbye</baz>
node comes before
</foo>
another node in return
document order. ($x/baz << $x/bar, $x/bar << $x/baz)
(: returns false, true :)

>> The node after let $x := <foo>


operator. Tests if a <bar>hello</bar>
<baz>goodbye</baz>
node comes after
</foo>
another node in return
document order. ($x/baz >> $x/bar, $x/bar >> $x/baz)
(: returns true, false :)

is The is operator. Tests let $x := <foo>


if a node is the exact <bar>hello</bar>
<baz>goodbye</baz>
same node as another
</foo>
(does not just test return
equality). ($x/baz is $x/bar, $x/bar is $x/bar)
(: returns false, true :)

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 53


MarkLogic Server XQuery Language

Node comparison tests are useful when creating logic that relies on document order. For example,
if you wanted to verify if a particular node came before another node, you can test as follows:

$x << $y

If this test returns true, you know that the node bound to $x comes before the node bound to $y,
based on document order.

4.8.2 Sequence and Item Operators


XQuery has separate operators for to compare sequences and items.The following tabled lists
XQuery operators for sequences and for items, along with a description and example for each
operator. These operators are used to form expressions that compare values, and those expressions
return a boolean value. This section consists of the following parts:

• Sequence Operators

• Item Operators

4.8.2.1 Sequence Operators


The following operators work on sequences. Note that a single item is a sequence, so the sequence
operators can work to compare single items. A sequence operator is true if any of the comparisons
are true.

Operator Description Example

= The equality operator. Operates on sequences 1 = 1 => true


(which can contain 0 or more items). Returns 1 = (1, 2) => true
(0, 3) = (1, 2) => false
true if the condition (is equal to) is satisfied for
any item in the sequence on the left compared
with any item in the sequence on the right.
> Greater than operator. Operates on sequences 1 > 1 => false
(which can contain 0 or more items). Returns 1 > (0, 1) => true
(0, 1) > (0, 1) => true
true if the condition (is greater than) is satisfied
for any item in the sequence on the left
compared with any item in the sequence on the
right.
>= Greater than or equal operator. Operates on 1 >= 1 => true
sequences (which can contain 0 or more items). 1 >= (1, 2) => true
(1, 2) >= (1, 2) => true
Returns true if the condition (is greater than or
equal to) is satisfied for any item in the
sequence on the left compared with any item in
the sequence on the right.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 54


MarkLogic Server XQuery Language

Operator Description Example

< Less than operator. Operates on sequences 1 < 1 => false


(which can contain 0 or more items). Returns 1 < (1, 2) => true
(1, 2) < (1, 2) => true
true if the condition (is less than) is satisfied for
any item in the sequence on the left compared
with any item in the sequence on the right.
<= Less than or equal operator. Operates on 1 <= 1 => true
sequences (which can contain 0 or more items). 1 <= (1, 2) => true
(1, 2) <= (1, 2) => true
Returns true if the condition (is less than or
equal to) is satisfied for any item in the
sequence on the left compared with any item in
the sequence on the right.
!= The not equal operator. Operates on sequences 1 != 1 => false
(which can contain 0 or more items). Returns 1 != (1, 2) => true
(1, 2) != (1, 2) => true
true if the condition (is not equal to) is satisfied
for any item in the sequence on the left
compared with any item in the sequence on the
right.

4.8.2.2 Item Operators


The following operators work on items. If you use these operators on a sequence, in the 1.0-ml
dialect they will perform function mapping, and the value will be the effective boolean value of
the sequence of results. In the 1.0 dialect, they will throw an XDMP-MANYITEMSEQ exception if you
try to compare a sequence of more than one item.

Operator Description Example

eq The equality operator. Operates only on single 1 eq 1 => true


items. 1 eq (1, 2) => error

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 55


MarkLogic Server XQuery Language

Operator Description Example

gt Greater than operator. Operates only on single 1 gt 1 => false


items.
ge Greater than or equal operator. Operates only 1 ge 1 => true
on single items.
lt Less than operator. Operates only on single 1 lt 1 => false
items.
le Less than or equal operator. Operates only on 1 le 1 => true
single items.
ne The not equal operator. Operates on single 1 ne 1 => false
items.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 56


MarkLogic Server XPath Quick Reference

5.0 XPath Quick Reference


72

The section provides a brief overview of the basics of XPath, and includes the following sections:

• Path Expressions

• XPath Axes and Syntax

• XPath 2.0 Functions

• Restricted XPath

For detailed information about XPath, see the W3C XPath 2.0 language reference
(http://www.w3.org/TR/xpath20/).

5.1 Path Expressions


XPath 2.0 is part of XQuery 1.0. XPath is used to navigate XML structures. In MarkLogic Server,
the XML structures can be stored in a database or they can be constructed in XQuery. A path
expression is an expression that selects nodes from an XML structure. Path expressions are a
fundamental way of identifying content in XQuery. Each path has zero or more steps, which
typically select XML nodes. Each step can have zero or more predicates, which constrain the
nodes that are selected. By combining multiple steps and predicates, you can create arbitrarily
complex path expressions. Consider the following path expression (which is in itself a valid
XQuery expression):

//LINE[fn:contains(., "To be, or not to be")]

Against the Shakespeare database (the XML is available at


http://www.oasis-open.org/cover/bosakShakespeare200.html), this XPath expression selects all LINE
elements that contain the text To be or not to be. You can then walk up the document to its
parent to see who says this line. as follows:

//LINE[fn:contains(., "To be, or not to be")]/../SPEAKER

This returns the following line:

<SPEAKER>HAMLET</SPEAKER>

You can make path expressions arbitrarily complex, which makes them a very powerful tool for
navigating through XML structures. For more details about path expressions, see the W3C
XQuery specification (http://www.w3.org/TR/xquery/#id-path-expressions).

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 57


MarkLogic Server XPath Quick Reference

A path expression always returns nodes in document order. If you want to return nodes in
relevance order (that is, relevance-ranked nodes), use the MarkLogic Server cts:search built-in
function or put the XPath in a FLWOR expression with an order by clause. Note that both XPath
expressions and cts:search expressions use any available indexes for fast expression evaluation.
For details on cts:search, see the Application Developer’s Guide and the MarkLogic XQuery and
XSLT Function Reference. For details about index options in MarkLogic Server, see the
Administrator’s Guide.

5.2 XPath Axes and Syntax


The following table shows the XPath axes supported in MarkLogic Server.

Shorthand (N/A
Axis Description
if no shorthand)

ancestor:: Selects all ancestor nodes, which N/A


includes the parent node, the parent’s
parent node, and so on.
ancestor-or-self:: Selects the current node as well as all N/A
ancestor nodes, which includes the
parent node, the parent’s parent node,
and so on.
attribute:: Selects the attributes of the current node. @

child:: Selects the immediate child nodes of the /


current node.
descendant:: Selects all descendant nodes (child N/A
nodes, their child nodes, and so on).
descendant-or-self:: Selects the current node as well as all //
descendant nodes (child nodes, their
child nodes, and so on).
following:: Selects everything following the current >>
node.
following-sibling:: Selects all sibling nodes (nodes at the N/A
same level in the XML hierarchy) that
come after the current node.
namespace:: Selects the namespace node of the N/A
current node.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 58


MarkLogic Server XPath Quick Reference

Shorthand (N/A
Axis Description
if no shorthand)

parent:: Selects the immediate parent of the ..


current node.
preceding:: Selects everything before the current <<
node.
preceding-sibling:: Selects all sibling nodes (nodes at the N/A
same level in the XML hierarchy) that
come before the current node.
property:: MarkLogic Server enhancement. Selects N/A
the properties fragment corresponding to
the current node.
self:: Selects the current node (the context .
node).

Keep in mind the following notes when using the XPath axes:

• XPath expressions are always returned in document order.


• Axes that look forward return in document order (closest to farthest away from the context
node).
• Axes that look backward return in reverse document order (closest to farthest away from
the context node).
• The context node is the node from which XPath steps are evaluated. The context node is
sometimes called the current node.

5.3 XPath 2.0 Functions


The XQuery standard functions are the same as the XPath 2.0 functions. These XQuery-standard
functions are all built into MarkLogic Server, and use the namespace bound to the fn prefix,
which is predefined in MarkLogic Server. For details on these functions, see the MarkLogic
XQuery and XSLT Function Reference reference.

5.4 Restricted XPath


MarkLogic supports the full XPath 2.0 grammar (plus extensions) in most places where you can
specify an XPath expression. However, some evaluation contexts restrict you to a subset of XPath
for performance and/or security reasons.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 59


MarkLogic Server XPath Quick Reference

The following features only support a restricted XPath subset. Each feature imposes different
limitations.

• Path Field and Path-Based Range Index Configuration

• Element Level Security

• Template Driven Extraction (TDE)

• Patch Feature of the Client APIs

• The extract-document-data Query Option

• The Optic API xpath Function

The following topics provide supporting details for the XPath restrictions applicable to these
features.

• Functions Callable in Predicate Expressions

• Indexable Path Expression Grammar

• Patch and Extract Path Expression Grammar

For detailed information about XPath, see the W3C XPath 2.0 language reference
(http://www.w3.org/TR/xpath20/).

5.4.1 Path Field and Path-Based Range Index Configuration


When you create a field or an index based on an XPath expression, these XPath expressions are
limited to the subset described here. This restriction applies to configuring the following:

• Path Range Index


• Field Range Index
• Geospatial Region Index
• Geospatial Path Index (a path-based point index)
To test an XPath expression for validity in these contexts, use the XQuery function
cts:valid-index-path or the Server-Side JavaScript function cts.validIndexPath.

Note: Avoid creating multiple path indexes that end with the same element/attribute, as
ingestion performance degrades with the number of path indexes that end in
common element/attributes.

The following list defines key aspects of the XPath restrictions. Additional restrictions may apply.
For a complete definition of the valid XPath subset, see “Indexable Path Expression Grammar” on
page 69.

• The only operators you can use in predicate expressions are comparison and logical
operators. (=, !=, <, <=, >=, >, eq, ne, lt, le, ge, gt, and, or).

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 60


MarkLogic Server XPath Quick Reference

• The right operand of a comparison in a predicate can only be a string literal, numeric
literal, or a sequence of string or numeric literals.
• You can only use forward axes in path steps. That is, you can use axes such as self::,
child::, descendant::, but you cannot use reverse axes such as parent::, ancestor::, or
preceding::. For details, see http://www.w3.org/TR/xpath/#predicates.

• You can only call functions on the “safe” function list in a predicate expression. For
details, see “Functions Callable in Predicate Expressions” on page 66.
• You cannot span a fragment root. Paths must be scoped within fragment roots.
• You cannot use an unnamed node test as the last path step. For example, when addressing
JSON, you cannot have a final path step such as node() or array-node(). You can use
named nodes, such as node('a').
The following table provides some examples of path expressions that meet the requirements of an
indexable path expression. This set of examples is not exhaustive.

Supported XPath Feature Valid Example

Absolute path /a/b

Relative path a/b

Intermediate path step containing a test for a /a/element(b)/c


named or unnamed node /a/node()/b
/a/object-node('b')/c

Final path step containing a test for an named /a/node('b')


node
Predicates, including those containing calls to /a/b[fn:matches(@attr, "is")]
safe functions or complex expressions /a/b[./c > 20]
/a/b[c < 20 and d = "dog"]/e
/a/b[c < 20][d = "dog"]/e
/a/b[fn:empty(./c)]

Forward axes a//b


/a/child::*/b
/a/descendant::b/c

Wildcards /a/*/b
/a/b/*

Namespace prefixes (assuming the namespace /ns:a/ns:b


binding is defined) /a/*:b

For more details on using namespace prefixes in indexable path expressions, see Using Namespace
Prefixes in Index Path Expressions in the Administrator’s Guide.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 61


MarkLogic Server XPath Quick Reference

The following table contains some examples of valid XPath expressions that cannot be used to
define path-based indexes. That is, expressions that could be used in other contexts, but for which
cts:valid-index-path or cts.validIndexPath returns false.

Unsupported XPath Feature Invalid Example

Final path step containing a test for an /a/b/node()


unnamed node /a/b/element()
/a/b/boolean-node()

Reverse axes /a/b/parent::*/c


/a/b/c/ancestor::*
/a/b/../c

Calls to unsafe functions in predicates a/b[xdmp:eval(5+3)]

Complex expressions as the right operand of a /a/b[c > fn:sum((1,2,3))]


comparison operator in a predicate a/b[c > (5+3)]

5.4.2 Element Level Security


When you define a protected path for use with Element Level Security, the protected path is
restricted to the same XPath subset as is used for creating path-based indexes. For details, see
“Path Field and Path-Based Range Index Configuration” on page 60 and “Indexable Path
Expression Grammar” on page 69.

To test whether or not an XPath expression is valid as a protected path, use the XQuery function
cts:valid-index-path or the Server-Side JavaScript function cts.validIndexPath.

To learn more about element level security, see Element Level Security in the Security Guide.

5.4.3 Template Driven Extraction (TDE)


When you create a TDE template, you identify the template context using XPath expressions.
These expressions are limited to the same XPath subset as is used for creating path-based indexes,
with the following differences:

• You can use "/" as a context XPath expression if the template has collection or directory
scope. For details, see Collections and Directories in the Application Developer’s Guide.
To test an XPath expression for validity in a TDE template, use the XQuery function
cts:valid-tde-context or the Server-Side JavaScript function cts.validTdeContext.

For more details and examples, see “Path Field and Path-Based Range Index Configuration” on
page 60 and “Indexable Path Expression Grammar” on page 69.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 62


MarkLogic Server XPath Quick Reference

To learn more about TDE, see Template Driven Extraction (TDE) in the Application Developer’s
Guide.

5.4.4 Patch Feature of the Client APIs


When you create a patch (or partial update) descriptor for use with the Java, Node.js, or REST
Client API, you identify the content to be updated using an XPath expression. These XPath
expressions are restricted to the XPath subset described here.

To test an XPath expression for validity in a patch descriptor, use the XQuery function
cts:valid-document-patch-path or the Server-Side JavaScript function
cts.validDocumentPatchPath.

The following list defines key aspects of the XPath restrictions. Additional restrictions may apply.
For a complete definition of the valid XPath subset, see “Patch and Extract Path Expression
Grammar” on page 71.

• The only operators you can use in predicate expressions are comparison and logical
operators. (=, !=, <, <=, >=, >, eq, ne, lt, le, ge, gt, and, or).
• The right operand of a comparison in a predicate can only be a string literal, numeric
literal, or a sequence of string or numeric literals.
• You can only use forward axes in path steps. That is, you can use axes such as self::,
child::, descendant::, but you cannot use reverse axes such as parent::, ancestor::, or
preceding::. For details, see http://www.w3.org/TR/xpath/#predicates.

• You can only call functions on the “safe” function list in a predicate expression. For
details, see “Functions Callable in Predicate Expressions” on page 66.
• You cannot span a fragment root. Paths must be scoped within fragment roots.
The following table provides some examples of path expressions that meet the requirements of an
indexable path expression. This set of examples is not exhaustive.

Supported XPath Feature Valid Example

Absolute path /a/b

Relative path a/b

Path step containing a test for a named or /a/node()/b


unnamed node /a/node()
/a/element(b)/c
/a/number-node()
/a/object-node('b')

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 63


MarkLogic Server XPath Quick Reference

Supported XPath Feature Valid Example

Predicates, including those containing calls to /a/b[fn:matches(@attr, "is")]


safe functions or complex expressions /a/b[./c > 20]
/a/b[c < 20 and d = "dog"]/e
/a/b[c < 20][d = "dog"]/e
/a/b[fn:empty(./c)]

Forward axes a//b


/a/child::*/b
/a/descendant::b/c

Wildcards /a/*/b
/a/b/*

Namespace prefixes (assuming the namespace /ns:a/ns:b


binding is defined) /a/*:b

The following table contains some examples of valid XPath expressions that cannot be used to
define path expressions in patch operations. That is, expressions that could be used in other
contexts, but for which cts:valid-document-patch-path or cts.validDocumentPatchPath returns
false. This set of examples is not exhaustive.

Unsupported XPath Feature Invalid Example

Reverse axes /a/b/parent::*/c


/a/b/c/ancestor::*
/a/b/../c

Calls to unsafe functions in predicates a/b[xdmp:eval(5+3)]

Complex expressions as the right operand of a /a/b[c > fn:sum((1,2,3))]


comparison operator in a predicate a/b[c > (5+3)]

To learn more about the document patch feature, see the following topics:

• Java Client API: Partially Updating Document Content and Metadata in the Java Application
Developer’s Guide
• Node.js Client API: Patching Document Content or Metadata in the Node.js Application
Developer’s Guide
• REST Client API: Partially Updating Document Content or Metadata in the REST Application
Developer’s Guide

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 64


MarkLogic Server XPath Quick Reference

5.4.5 The extract-document-data Query Option


The XQuery Search API, Server-Side JavaScript Jsearch API, and the Java, Node.js, and REST
client APIs support a query option named extract-document-data that enables you to specify
portions of a matched document to be returned in document search results. You identify the
content to be extracted by specifying an XPath expression in the extract-path portion of the
option.

The extract-path is restricted to the same XPath subset that is described in “Patch Feature of the
Client APIs” on page 63.

To test an XPath expression for validity as an extract-path value, use the XQuery function
cts:valid-extract-path or the Server-Side JavaScript function cts.validExtractPath.

To learn more about the extract-document-data query option, see extract-document-data in the
Search Developer’s Guide. To learn more about the equivalent JSearch feature, see Extracting
Portions of Each Matched Document in the Search Developer’s Guide.

The Java and Node.js Client APIs support a similar feature for Optic searches. For details, see
“The Optic API xpath Function” on page 65.

5.4.6 The Optic API xpath Function


Optic searches enable you to extract child nodes from a column with node values. You identify
these nodes with an XPath expression. This XPath expression is restricted to the subset described
in limited to the XPath subset described in “Patch Feature of the Client APIs” on page 63.

The restrictions apply to the following contexts:

• Server-Side JavaScript Optic API: op.xpath


• XQuery Optic API: op:xpath
• Node.js Client API: planBuilder.xpath
• Java Client API: com.marklogic.client.expression.PlanBuilder.xpath
To test an XPath expression for validity as an Optic xpath value, use the XQuery function
cts:valid-optic-path or the Server-Side JavaScript function cts.validOpticPath.

To learn more about the Optic API, see the following topics:

• XQuery and Server-Side JavaScript: Optic API for Multi-Model Data Access in the
Application Developer’s Guide
• Java Client API: Optic Java API for Relational Operations in the Java Application
Developer’s Guide
• Node.js Client API: Using the Optic API for Relational Operations in the Node.js Application
Developer’s Guide

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 65


MarkLogic Server XPath Quick Reference

5.4.7 Functions Callable in Predicate Expressions


In a restricted XPath subset that supports function calls in predicates, you can only call functions
known to be performant and secure in the context in which the restricted XPath applies. The
following topics list these “safe” functions:

• String Functions

• Logical and Data Validation Functions

• Date and Time Functions

• Type Casting Functions

• Mathematical Functions

• Miscellanious Functions

5.4.7.1 String Functions

Note: These functions are not supported by XQuery 0.9-ml, which has been deprecated.

fn:codepoint-equal fn:iri-to-uri fn:string-join

fn:codepoints-to-string fn:last fn:string-length

fn:compare fn:lower-case fn:string-to-codepoints

fn:concat fn:matches fn:subsequence

fn:contains fn:normalize-space fn:substring

fn:encode-for-uri fn:normalize-unicode fn:substring-after

fn:ends-with fn:position fn:substring-before

fn:escape-html-uri fn:remove fn:tokenize

fn:escape-uri fn:replace fn:translate

fn:format-number fn:reverse fn:upper-case

fn:insert-before fn:starts-with

5.4.7.2 Logical and Data Validation Functions


• fn:boolean

• fn:empty

• fn:exists

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 66


MarkLogic Server XPath Quick Reference

• fn:false

• fn:not

• fn:true

5.4.7.3 Date and Time Functions

fn:adjust-date-to-timezone fn:years-from-duration sql:seconds

fn:adjust-dateTime-to-timezone fn:day-from-date sql:timestampadd

fn:adjust-time-to-timezone fn:day-from-dateTime sql:timestampdiff

fn:month-from-date fn:days-from-duration sql:week

fn:month-from-dateTime fn:format-date sql:weekday

fn:months-from-duration fn:formate-dateTime sql:year

fn:seconds-from-dateTime fn:format-time sql:yearday

fn:seconds-from-duration fn:hours-from-dateTime sql:dateadd

fn:seconds-from-time fn:hours-from-duration sql:datediff

fn:minutes-from-dateTime fn:hours-from-time sql:datepart

fn:minutes-from-duration sql:day xdmp:dayname-from-date

fn:minutes-from-time sql:dayname xdmp:quarter-from-date

fn:timezone-from-date sql:hours xdmp:week-from-date

fn:timezone-from-dateTime sql:minutes xdmp:weekday-from-date

fn:timezone-from-time sql:month xdmp:yearday-from-date

fn:year-from-date sql:monthname xdmp:parse-yymmdd

fn:year-from-dateTime sql:quarter xdmp:parse-dateTime

5.4.7.4 Type Casting Functions

fn:number xs:float xs:gMonth

fn:string xs:double xs:gDay

xs:string xs:boolean xs:duration

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 67


MarkLogic Server XPath Quick Reference

xs:decimal xs:dateTime xs:anyURI

xs:integer xs:date xs:dayTimeDuration

xs:long xs:time xs:yearMonthDuration

xs:int xs:gYearMonth xdmp:castable-as

xs:short xs:gYear

xs:byte xs:gMonthDay

5.4.7.5 Mathematical Functions

fn:abs math:cosh math:modf

fn:ceiling math:cot math:pi

fn:floor math:degrees math:pow

fn:round math:exp math:radians

fn:round-half-to-even math:fabs math:sin

math:acos math:floor math:sinh

math:asin math:fmod math:sqrt

math:atan math:frexp math:tan

math:atan2 math:ldexp math:tanh

math:ceil math:log math:trunc

math:cos math:log10

5.4.7.6 Miscellanious Functions

fn:head fn:sum sem:invalid-datatype

fn:tail fn:count sem:typed-literal

fn:base-uri fn:avg cts:point

fn:document-uri sem:uuid xdmp:node-metadata-value

fn:lang sem:uuid-string xdmp:node-metadata

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 68


MarkLogic Server XPath Quick Reference

fn:local-name sem:bnode xdmp:node-kind

fn:name sem:datatype xdmp:node-uri

fn:namespace-uri sem:sameTerm xdmp:path

fn:node-name sem:lang xdmp:type

fn:number sem:iri

fn:root sem:unknown

fn:min sem:unknown-datatype

fn:max sem:invalid

5.4.8 Indexable Path Expression Grammar


Most users can rely on the examples in “Path Field and Path-Based Range Index Configuration”
on page 60 and the validity checking function appropriate to the context to develop valid path
range index expressions. For example, use cts:valid-index-path or cts.validIndexPath to test a
path expression.

For advanced users, this section contains a detailed grammar that defines the subset of XPath you
can use to define path-based indexes. The same grammar applies to XPath expressions for the
following features. Any differences are called out below.

• Template Driven Extraction (TDE): TDE also allows the use of “/” as a TDE context XPath
expression in some cases.
• Element Level Security: No differences.
The grammar is derived from the W3C XML Path Language specification; for details, see
http://www.w3.org/TR/xpath/. If you find it easier to explore the grammar graphically, the BNF is
suitable for use with many tools that generate “railroad diagrams” from BNF, such as
http://bottlecaps.de/rr/ui.

The following grammar expresses the XPath subset you can use to define path-based indexes.
Note that FunctionalCall in the grammar can only be a call to one of the functions listed in
“Functions Callable in Predicate Expressions” on page 66. Also, an unamed KindTest cannot be
used as the leaf step.

IndexablePathExpr ::= (PathExpr)* (("/" | "//") LeafExpr Predicates)


LeafExpr ::= "(" UnionExpr ")" | LeafStep
PathExpr ::= ("/" RelativePathExpr?)
| ("//" RelativePathExpr)
| RelativePathExpr
RelativePathExpr ::= UnionExpr | "(" UnionExpr ")"
UnionExpr ::= GeneralStepExpr ("|" GeneralStepExpr)*
GeneralStepExpr ::= ("/" | "//")? StepExpr (("/" | "//")? StepExpr)*

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 69


MarkLogic Server XPath Quick Reference

StepExpr ::= ForwardStep Predicates


ForwardStep ::= (ForwardAxis AbbreviatedFwdStep)
| AbbreviatedFwdStep
AbbreviatedFwdStep ::= "." | ("@" NameTest) | NameTest | KindTest
LeafStep ::= ("@"QName) | QName | NamedKindTest
NameTest ::= QName | Wildcard
Wildcard ::= "*" | NCName ":" "*" | "*" ":" NCName
QName ::= PrefixedName | UnprefixedName
PrefixedName ::= Prefix ":" LocalPart
UnprefixedName ::= LocalPart
Prefix ::= NCName
LocalPart ::= NCName
NCName ::= Name - (Char* ":" Char*) /* An XML Name, minus the ":"
*/
Name ::= NameStartChar (NameChar)*
QuotedNCName ::= "'" NCName "'"
| '"' NCName '"'

Predicates ::= Predicate*


Predicate ::= PredicateExpr | "[" Digit+ "]"
Digit ::= [0-9]
PredicateExpr ::= "[" PredicateExpr "and" PredicateExpr "]"
| "[" PredicateExpr "or" PredicateExpr "]"
| "[" ComparisonExpr "]" | "[" FunctionExpr "]"
ComparisonExpr ::= RelativePathExpr GeneralComp SequenceExpr
| RelativePathExpr ValueComp Literal
| PathExpr
FunctionExpr ::= FunctionCall GeneralComp SequenceExpr
| FunctionCall ValueComp Literal
| FunctionCall
GeneralComp ::= "=" | "!=" | "<" | "<=" | ">" | ">="
ValueComp ::= "eq" | "ne" | "lt" | "le" | "gt" | "ge"
SequenceExpr ::= Literal+
Literal ::= NumericLiteral | StringLiteral

KindTest ::= "attribute" "(" QNameOrWildcard? ")"


| "element" "(" QNameOrWildcard? ")"
| "array-node" "(" QuotedNCName? ")"
| "object-node" "(" QuotedNCName? ")"
| "boolean-node" "(" QuotedNCName? ")"
| "number-node" "(" QuotedNCName? ")"
| "null-node" "(" QuotedNCName? ")"
| "node" "(" QuotedNCName? ")"
| "schema-element" "(" QName ")"
| "schema-attribute" "(" QName ")"
| "processing-instruction" "(" (NCName |
StringLiteral)? ")"
NamedKindTest ::= "attribute" "(" QNameOrWildcard ")"
| "element" "(" QNameOrWildcard ")"
| "array-node" "(" QuotedNCName ")"
| "object-node" "(" QuotedNCName ")"
| "boolean-node" "(" QuotedNCName ")"
| "number-node" "(" QuotedNCName ")"
| "null-node" "(" QuotedNCName ")"

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 70


MarkLogic Server XPath Quick Reference

| "node" "(" QuotedNCName ")"


| "schema-element" "(" QName ")"
| "schema-attribute" "(" QName ")"
| "processing-instruction" "(" (NCName |
StringLiteral) ")"
QNameOrWildcard ::= QName | "*"

5.4.9 Patch and Extract Path Expression Grammar


Most users can rely on the summary and examples in “Patch Feature of the Client APIs” on
page 63 and the validity checking function appropriate to the context to develop valid path
expressions. For example, use cts:valid-document-patch-path or cts.documentPatchPath to test
a path expression.

For advanced users, this section contains a detailed grammar that defines the subset of XPath you
can use with the following features. More details and examples are available in the referenced
topics.

• Patch Feature of the Client APIs

• The extract-document-data Query Option

• The Optic API xpath Function

The grammar is derived from the W3C XML Path Language specification; for details, see
http://www.w3.org/TR/xpath/. If you find it easier to explore the grammar graphically, the BNF is
suitable for use with many tools that generate “railroad diagrams” from BNF, such as
http://bottlecaps.de/rr/ui.

The following grammar expresses the XPath subset. Note that FunctionalCall in the grammar can
only be a call to one of the functions listed in “Functions Callable in Predicate Expressions” on
page 66.

ExtractPathExpr ::= ("/" RelativePathExpr?)


| ("//" RelativePathExpr)
| RelativePathExpr
RelativePathExpr ::= UnionExpr | "(" UnionExpr ")"
UnionExpr ::= GeneralStepExpr ("|" GeneralStepExpr)*
GeneralStepExpr ::= ("/" | "//")? StepExpr (("/" | "//")? StepExpr)*
StepExpr ::= ForwardStep Predicates
ForwardStep ::= (ForwardAxis AbbreviatedFwdStep)
| AbbreviatedFwdStep
AbbreviatedFwdStep ::= "." | ("@" NameTest) | NameTest | KindTest
NameTest ::= QName | Wildcard
Wildcard ::= "*" | NCName ":" "*" | "*" ":" NCName
QName ::= PrefixedName | UnprefixedName
PrefixedName ::= Prefix ":" LocalPart
UnprefixedName ::= LocalPart
Prefix ::= NCName
LocalPart ::= NCName
NCName ::= Name - (Char* ":" Char*) /* An XML Name, minus

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 71


MarkLogic Server XPath Quick Reference

the ":" */
Name ::= NameStartChar (NameChar)*
Predicates ::= Predicate*
Predicate ::= PredicateExpr | "[" Digit+ "]"
Digit ::= [0-9]
PredicateExpr ::= "[" PredicateExpr "and" PredicateExpr "]"
| "[" PredicateExpr "or" PredicateExpr "]"
| "[" ComparisonExpr "]" | "[" FunctionExpr "]"
ComparisonExpr ::= RelativePathExpr GeneralComp SequenceExpr
| RelativePathExpr ValueComp Literal
| PathExpr
FunctionExpr ::= FunctionCall GeneralComp SequenceExpr
| FunctionCall ValueComp Literal
| FunctionCall
GeneralComp ::= "=" | "!=" | "<" | "<=" | ">" | ">="
ValueComp ::= "eq" | "ne" | "lt" | "le" | "gt" | "ge"
SequenceExpr ::= Literal+
Literal ::= NumericLiteral | StringLiteral
KindTest ::= ElementTest
| AttributeTest
| CommentTest
| TextTest
| ArrayNodeTest
| ObjectNodeTest
| BooleanNodeTest
| NumberNodeTest
| NullNodeTest
| AnyKindTest
| DocumentTest
| SchemaElemTest
| SchemaAttrTest
| PITest
TextTest ::= "text" "(" ")"
CommentTest ::= "comment" "(" ")"
AttributeTest ::= "attribute" "(" QNameOrWildcard? ")"
ElementTest ::= "element" "(" QNameOrWildcard? ")"
ArrayNodeTest ::= "array-node" "(" QuotedNCName? ")"
ObjectNodeTest ::= "object-node" "(" QuotedNCName? ")"
BooleanNodeTest ::= "boolean-node" "(" QuotedNCName? ")"
NumberNodeTest ::= "number-node" "(" QuotedNCName? ")"
NullNodeTest ::= "null-node" "(" QuotedNCName? ")"
AnyKindTest ::= "node" "(" QuotedNCName? ")"
SchemaElemTest ::= "schema-element" "(" QName ")"
SchemaAttrTest ::= "schema-attribute" "(" QName ")"
PITest ::= "processing-instruction" "(" (NCName |
StringLiteral)? ")"
QNameOrWildcard ::= QName | "*"
QuotedNCName ::= "'" NCName "'"
| '"' NCName '"'

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 72


MarkLogic Server Understanding XML Namespaces in XQuery

6.0 Understanding XML Namespaces in XQuery


82

XQuery is designed to work well with XML content, allowing many convenient ways to search
through XML elements and attributes as well as making it easy to output XML from an XQuery
program. When working with XML, you must understand a little about the XML data model, and
one fundamental aspect of the XML data model is namespaces. This chapter describes XML
namespaces and how they are important in XQuery, and includes the following sections:

• XML QNames, Local Names, and Namespaces

• Everything Is In a Namespace

• XML Data Model Versus Serialized XML

• Declaring a Default Element Namespace in XQuery

• Tips For Constructing QNames

• Predefined Namespace Prefixes for Each Dialect

6.1 XML QNames, Local Names, and Namespaces


XML uses qualified names, also called QNames, to uniquely identify elements and attributes. A
QName for an XML element or attribute has two parts: the namespace name and the local name.
Together, the namespace and local name uniquely define how the element or attribute is
identified. Additionally, the QName also retains its namespace prefix, if there is one. A
namespace prefix binds a namespace URI to a specified string (the string is the prefix).

6.2 Everything Is In a Namespace


In XML and XQuery, element and attribute nodes are always in a namespace, even if that
namespace is the empty namespace (sometimes called no namespace). Each namespace has a
uniform resource identifier (URI) associated. A URI is essentially a unique string that identifies
the namespace. That string can be bound to a namespace prefix, which is just a shorthand string
which is used to identify a (usually longer) namespace name. When something is in the empty
namespace, the namespace name is the empty string ("").

There can also be a default element namespace defined for the module, as described in “Declaring
a Default Element Namespace in XQuery” on page 78. The fact that every element is in a
namespace, along with the fact that XPath expressions of an unknown node return the empty
sequence, make it easy to have simple coding errors (or even typographic errors) that cause your
query to be a valid XPath expression, but to return the empty string. For example, if you have a
simple typographical error in a namespace declaration, then XPath expressions that you might
expect to return nodes might return the empty sequence. Consider the following query against a
database with XHTML content:

xquery version "1.0-ml";


declare namespace xh="http://www.w3.org/1999/html";
//xh:p

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 73


MarkLogic Server Understanding XML Namespaces in XQuery

You might expect this to return all of the XHTML p elements in the database, but instead it
returns nothing (the empty sequence). If you look closely, though, you will notice that the
namespace URI is misspelled (it is missing the x in xhtml). If you keep in mind that everything is
in a namespace, it can help find many simple XQuery coding errors. The correct version of this
query is as follows, and will return all of the XHTML p elements:

xquery version "1.0-ml";


declare namespace xh="http://www.w3.org/1999/xhtml";
//xh:p

6.3 XML Data Model Versus Serialized XML


This section highlights the difference between the XML data model, used to programmatically
access XML content, and the serialized form of XML, used to display the XML in
human-readable form. The following topics are covered:

• XQuery Accesses the XML Data Model

• Serialized XML: Human-Readable With Angle Brackets

• Understanding Namespace Inheritance With the xmlns Attribute

6.3.1 XQuery Accesses the XML Data Model


When an XQuery program accesses XML, it accesses it through the XML data model. The XML
data model access nodes via their QNames, which are pairs of namespace name and local name.
The XML data model does not store namespace prefixes. You can use namespace prefixes to
access XML if those prefixes are in-scope in your XQuery (that is, if the prefixes are bound to a
namespace). In-scope prefixes are a combination of any prefixes bound to a namespace in your
query and the predefined namespace prefixes defined in “Predefined Namespace Prefixes for
Each Dialect” on page 79.

The XML data model is aware of XML schema, and all XML nodes can optionally have XML
types (for example, xs:string, xs:dateTime, xs:integer, and so on). When you are creating
library functions that might be called from a number of contexts, knowing that XQuery accesses
the XML data model can help you to make your code robust. For example, you might have code
that explicitly (or implicitly, using the XQuery rules) casts nodes to a particular XML type,
enforcing strong typing in your code.

6.3.2 Serialized XML: Human-Readable With Angle Brackets


When XML nodes are transformed from their internal, XML data model representation to a
human-readable form, the process is known as XML serialization. A serialized XML node
contains all of the namespace information, although some namespace prefixes may or may not be
included in the serialization. Serialized XML does not generally contain the type information or
the schema information; it is up to the XQuery program to specify a schema for a given XML
representation.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 74


MarkLogic Server Understanding XML Namespaces in XQuery

When serializing XML, there are five XML reserved characters that are serialized with their
corresponding XML entities. These characters cannot appear as content in a serialized XML text
node. The following table shows these five characters:

Character XML Entity Name of Character

" &quot; double quotation mark


& &amp; ampersand
' &apos; apostrophe
< &lt; less-than sign
> &gt; greater-than sign

There are different ways to serialize the same XML content. The way XML content is serialized
depends on how the content is constructed, the various namespace declarations in the query, and
how the XML content was loaded into MarkLogic Server (for content loaded into a database). In
particular, the ampersand character can be tricky to construct in an XQuery string, as it is an
escape character to the XQuery parser. The ways to construct the ampersand character in XQuery
are:

• Use the XML entity syntax (for example, &amp;).


• Use a CDATA element (<![CDATA[element content here]]>), which tells the XQuery
parser to read the content as character data.
• Use the repair option on xdmp:document-load, xdmp:document-get, or xdmp:unquote.
For example, consider the following query:

xquery version "1.0-ml";


declare default element namespace "my.namespace.hello";

<some-element><![CDATA[element content with & goes


here]]></some-element>

If you evaluate this query, it returns the following serialization of the specified element:

<some-element xmlns="my.namespace.hello">element content


with &amp; goes here</some-element>

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 75


MarkLogic Server Understanding XML Namespaces in XQuery

If you consider a similar query with a namespace prefix binding instead of the default element
namespace declaration:

xquery version "1.0-ml";


declare namespace hello="my.namespace.hello";

<hello:some-element><![CDATA[element content with & goes


here]]></hello:some-element>

If you evaluate this query, it returns the following serialization of the specified element:

<hello:some-element xmlns:hello="my.namespace.hello">element
content with &amp; goes here</hello:some-element>

Notice that in both cases, the & character is escaped as an XML entity, and in each case there is an
xmlns attribute added to the serialization. In the first example, there is no prefix bound to the
namespace, but in the second one there is (because it is declared in the query). Both serializations
represent the exact same XML data model.

To construct the double quotation mark and apostrophe characters within a string quoted with one
of these characters (' or "), you can use the character to escape itself, or you can quote the string
with the other quote character, as follows:

"""" (: returns a single character: " :)

'"' (: returns a single character: " :)

'''' (: returns a single character: ' :)

"'" (: returns a single character: ' :)

6.3.3 Understanding Namespace Inheritance With the xmlns Attribute


As seen in the previous example, XML has a namespace declaration called xmlns, which is used to
specify namespaces in XML. An xmlns namespace declaration looks like an attribute (although it
is not actually an attribute). It can either stand by itself or have a prefix appended to it, separated
by a colon ( : ) character. Any xmlns namespace declaration is inherited by all of its child
elements, and if it has a prefix appended to it, the children also inherit the namespace prefix
binding.

For example, the following XML serialization specifies that the XHTML namespace is inherited
from the root element:

<html xmlns="http://www.w3.org/1999/xhtml">
<body><p>This is in the XHTML namespace</p></body>
</html>

Each of the elements (html, body, and p in this example) are in the XHTML namespace.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 76


MarkLogic Server Understanding XML Namespaces in XQuery

Similarly, an xmlns namespace declaration with a prefix appended specifies that the prefix is
inherited by the element children.

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:my="my.namespace">
<body>
<p>This is in the XHTML namespace</p>
<my:p>This element is in my.namespace</my:p>
</body>
</html>

One other sublety about default namespaces using the xmlns attribute in constructed elements is
that any XPath statement that is constructed within an element constructor that uses an xmlns
default namespace will default to the namespace of the parent element. This can be unexpected if
you are trying to write an XPath expression using QNames in no namespace. The following code
sample demonstrates how this namespace XPath inheritance works.

xquery version "1.0-ml";

declare namespace foo="foo";

(: notice the element constructed in $x is in no namespace :)


let $x := <a><b>hello</b></a>
return
(
<blah xmlns="foo">{$x/b}</blah>,
<foo:blah>{$x/b}</foo:blah>
)

(:
Returns:
<blah xmlns="foo"/>
<foo:blah xmlns:foo="foo"><b>hello</b></foo:blah>

Notice how in the first part of the return, the "b" in $x/b
inherits the namespace from the parent element, which is
constructed with a default namespace (xmlns="foo"),
so it returns empty.
In the second $x/b, the "b" is in no namespace.
:)

There are some other subtleties of namespace inheritance in XML. For more details, see the XML
Schema specification (http://www.w3.org/XML/Schema).

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 77


MarkLogic Server Understanding XML Namespaces in XQuery

6.4 Declaring a Default Element Namespace in XQuery


An XQuery program can declare a namespace as the default element namespace for any elements
that do not have a namespace. By default, the default element namespace is no namespace, which
is denoted by the empty string URI (""). If you want to define a default element namespace for a
query, add a declaration to the prolog similar to the following, which declares the XHTML
namespace (http://www.w3.org/1999/xhtml) as the default element namespace:

declare default element namespace "http://www.w3.org/1999/xhtml";

An XQuery program that has this prolog declaration will use the XHTML namespace for all
elements where a namespace is not explicitly defined (for example, with a namespace prefix).

Declaring a default element namespace is a convenience and a style which some programmers
find useful. While it is sometimes convenient (so you do not have to prefix element names, for
example), it can also cause confusion in larger programs that use multiple namespaces, so for
more complex programming efforts, explicitly defining namespaces is usually more clear.

6.5 Tips For Constructing QNames


In XML, elements and attributes are uniquely identified by a qualified names (QNames, as
described in “XML QNames, Local Names, and Namespaces” on page 73). A QName is a pairing
of a namespace name and a local name, and it uniquely describes an element or attribute name.
XQuery also uses QNames to uniquely identify function names, variable names, and type names.

There are many functions that use QNames in XQuery, and all of the rules for in-scope
namespaces apply to constructing those QNames. For example, if the namespace prefix my is
bound to the namespace URI my.namespace in the scope of a query, then the following would
construct a QName in that namespace with the local name some-element:

xs:QName("my:some-element")

Similarly, you can construct this QName using the fn:QName function as follows:

fn:QName("my.namespace", "some-element")

Because a prefix is not specified in the second parameter to the above function, the QName is
defined to have a prefix of the empty string ("").

Similarly, you can construct this QName with the prefix my by using the fn:QName function as
follows:

fn:QName("my.namespace", "my:some-element")

XQuery functions and other language constructs that take a QName can use any in-scope
namespace prefixes. For example, the following will construct an html element in the XHTML
namespace:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 78


MarkLogic Server Understanding XML Namespaces in XQuery

xquery version "1.0-ml";


declare namespace xh="http://www.w3.org/1999/xhtml";

element xh:html { "This is in the xhtml namespace." }

6.6 Predefined Namespace Prefixes for Each Dialect


This section lists the namespaces that are predefined for each of the dialects supported in
MarkLogic Server. When a prefix is predefined, you can use it in your XQuery without the need
to define it in a declare namespace prolog statement. It contains the following parts:

• 1.0-ml Predefined Namespaces

• 1.0 Predefined Namespaces

6.6.1 1.0-ml Predefined Namespaces


The following table lists the namespace prefixes and the corresponding URIs to which they are
bound that are predefined in the 1.0-ml XQuery dialect.

1.0-ml
Predefined Used For Namespace URI
Prefix

cts MarkLogic Server http://marklogic.com/cts


search functions
(Core Text Services)
dav Used with WebDAV DAV:

dbg Debug Built-In http://marklogic.com/xdmp/debug


functions
dir MarkLogic Server http://marklogic.com/xdmp/directory
directory XML
err namespace for http://www.w3.org/2005/xqt-errors
XQuery and XPath
errors
error MarkLogic Server http://marklogic.com/xdmp/error
error namespace
fn XQuery standard http://www.w3.org/2005/xpath-functions
function namespace

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 79


MarkLogic Server Understanding XML Namespaces in XQuery

1.0-ml
Predefined Used For Namespace URI
Prefix

local local namespace for http://www.w3.org/2005/xquery-local-functions


functions defined in
main modules
lock MarkLogic Server http://marklogic.com/xdmp/lock
locks
map MarkLogic Server http://marklogic.com/xdmp/map
maps
math math Built-In http://marklogic.com/xdmp/math
functions
prof profile Built-In http://marklogic.com/xdmp/profile
functions
prop MarkLogic Server http://marklogic.com/xdmp/property
properties
sec security Built-In http://marklogic.com/xdmp/security
functions
sem semantic Built-In http://marklogic.com/semantics
functions
spell spelling correction http://marklogic.com/xdmp/spell
functions
xdmp MarkLogic Server http://marklogic.com/xdmp
Built-In functions
xml XML namespace http://www.w3.org/XML/1998/namespace

xmlns xmlns namespace http://www.w3.org/2000/xmlns/

xqe deprecated http://marklogic.com/xqe


MarkLogic Server
xqe namespace
xqterr XQuery test suite http://www.w3.org/2005/xqt-errors
errors (same as err)
xs XML Schema http://www.w3.org/2001/XMLSchema
namespace

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 80


MarkLogic Server Understanding XML Namespaces in XQuery

6.6.2 1.0 Predefined Namespaces


The following table lists the namespace prefixes and the corresponding URIs to which they are
bound that are predefined in the 1.0 XQuery dialect (strict XQuery 1.0).

1.0
Predefined Used For Namespace URI
Prefix

err namespace for http://www.w3.org/2005/xqt-errors


XQuery and XPath
errors
fn XQuery standard http://www.w3.org/2005/xpath-functions
function namespace
local local namespace for http://www.w3.org/2005/xquery-local-functions
functions defined in
main modules
xml XML namespace http://www.w3.org/XML/1998/namespace

xmlns xmlns namespace http://www.w3.org/2000/xmlns/

xs XML Schema http://www.w3.org/2001/XMLSchema


namespace

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 81


MarkLogic Server Understanding XML Namespaces in XQuery

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 82


MarkLogic Server XSLT in MarkLogic Server

7.0 XSLT in MarkLogic Server


89

In MarkLogic Server, you have both the XQuery and XSLT languages available. You can use one
or both of these languages as needed. This chapter briefly describes some of the XSLT language
features and describes how to run XSLT in MarkLogic Server, and includes the following
sections:

• XSLT 2.0

• Invoking and Evaluating XSLT Stylesheets

• MarkLogic Server Extensions to XSLT

• Invoking Stylesheets Directly Using the XSLT Rewriter

• XSLT, XQuery, or Both

7.1 XSLT 2.0


MarkLogic Server implements the W3C XSLT 2.0 recommendation. XSLT 2.0 includes
compatibility mode for 1.0 stylesheets. XSLT is a programming languages designed to make it
easy to transform XML.

For details about the XSLT 2.0 recommendation, see the W3C website:

• http://www.w3.org/TR/xslt20/
An XSLT stylesheet is an XML document. Each element is an instruction in the XSLT language.
For a summary of the syntax of the various elements in an XSLT stylesheet, see
https://www.w3.org/TR/xslt20/#element-syntax-summary.

7.2 Invoking and Evaluating XSLT Stylesheets


To run an XSLT stylesheet in MarkLogic Server, you run one of the following functions from an
XQuery context:

• xdmp:xslt-invoke
• xdmp:xslt-eval

The xdmp:xslt-invoke function invokes an XSLT stylesheet from the App Server root, and the
xdmp:xslt-eval function takes a stylesheet as an element and evaluates it as an XSLT stylesheet.
As part of running a stylesheet, you pass the stylesheet a node to operate on. For details on
xdmp:xslt-invoke and xdmp:xslt-eval, see the MarkLogic XQuery and XSLT Function Reference.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 83


MarkLogic Server XSLT in MarkLogic Server

7.3 MarkLogic Server Extensions to XSLT


Besides the ability to invoke and evaluate XSLT stylesheets from an XQuery context (as
described in “Invoking and Evaluating XSLT Stylesheets” on page 83), there are several
extensions to XSLT available in MarkLogic Server. This section describes those extensions and
includes the following parts:

• Calling Built-In XQuery Functions in a Stylesheet

• Importing XQuery Function Libraries to a Stylesheet

• Try/Catch XSLT Instruction

• EXSLT Extensions

• xdmp:dialect Attribute

• Notes on Importing Stylesheets With <xsl:import>

7.3.1 Calling Built-In XQuery Functions in a Stylesheet


You can call any of the MarkLogic Server Built-In XQuery functions from an XSLT stylesheet.

7.3.2 Importing XQuery Function Libraries to a Stylesheet


In addition to using <xsl:import> to import other XSLT stylesheets into your stylesheet, you can
use the <xdmp:import-module> instruction to import an XQuery library module to an XSLT
stylesheet. Once you have imported the module, any functions defined in the module are available
to that stylesheet. When using the <xdmp:import-module> instruction, you must specify xdmp as a
value of the extension-element-prefixes attribute on the <xsl:stylesheet> instruction and you
also must bind the xdmp prefix to its namespace in the stylesheet XML.

The following is an example of an <xdmp:import-module> instruction:

xquery version "1.0-ml";

xdmp:xslt-eval(
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xdmp="http://marklogic.com/xdmp"
xmlns:search="http://marklogic.com/appservices/search"
extension-element-prefixes="xdmp"
version="2.0">
<xdmp:import-module
namespace="http://marklogic.com/appservices/search"
href="/MarkLogic/appservices/search/search.xqy"/>
<xsl:template match="/">
<xsl:copy-of select="search:search('hello')"/>
</xsl:template>
</xsl:stylesheet>
,
document{ <doc/> })

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 84


MarkLogic Server XSLT in MarkLogic Server

Similarly, you can import an XSLT sytlesheet into an XQuery library, as described in “Importing
XQuery Function Libraries to a Stylesheet” on page 84.

7.3.3 Try/Catch XSLT Instruction


You can use the <xdmp:try> instruction to create a try/catch expression in XSLT. When using the
<xdmp:try> instruction, you must specify xdmp as a value of the extension-element-prefixes
attribute on the <xsl:stylesheet> instruction and you also must bind the xdmp prefix to its
namespace in the stylesheet XML.

The following is an example of a try/catch in XSLT. This example returns the error XML, which
is bound to the variable named e in the name attribute of the <xdmp:catch> instruction.

xquery version "1.0-ml";

xdmp:xslt-eval(
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xdmp="http://marklogic.com/xdmp"
extension-element-prefixes="xdmp"
version="2.0">
<xsl:template match="/">
<xdmp:try>
<xsl:value-of select="error(xs:QName('MY-ERROR'),
'This is an error')"/>
<xdmp:catch name="e">
<xsl:copy-of select="$e"/>
</xdmp:catch>
</xdmp:try>
</xsl:template>
</xsl:stylesheet>
,
document{<doc>hello</doc>})

7.3.4 EXSLT Extensions


MarkLogic Server includes many of the EXSLT extensions (http://www.exslt.org/). The extensions
include the exslt:node-set and exslt:object-type functions and the exsl:document instruction.
For details about the functions, see the MarkLogic XQuery and XSLT Function Reference and the
EXSLT web site.

The following is an example of the exsl:document instruction. Note that this is essentially the
same as the xsl:result-document instruction, which is part of XSLT 2.0.

xquery version "1.0-ml";


(: Assumes this is run from a file called c:/mypath/exsl.xqy :)
xdmp:set-response-content-type("text/html"),
let $nodes := xdmp:xslt-eval(
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
xmlns:xdmp="http://marklogic.com/xdmp"

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 85


MarkLogic Server XSLT in MarkLogic Server

version="2.0">
<xsl:template match="/">
<html>
<head><title>Frame example</title></head>
<frameset cols="20%, 80%">
<frame src="toc.html"/>
<exsl:document href="toc.html">
<html>
<head><title>Table of Contents</title></head>
<body>
<xsl:apply-templates mode="toc" select="*"/>
</body>
</html>
</exsl:document>
<frame src="body.html"/>
<exsl:document href="body.html">
<html>
<head><title>Body</title></head>
<body>
<xsl:apply-templates select="*"/>
</body>
</html>
</exsl:document>
</frameset>
</html>
</xsl:template>
</xsl:stylesheet>,
document{element p { "hello" }})
for $node at $i in $nodes
return
if ( fn:document-uri($node) )
then xdmp:save(
fn:resolve-uri(fn:document-uri($node),
"C://mypath/exsl.xqy"), $node)
else ($node)

The above query will save the two documents created with exsl:document to the App Server root
on the filesystem, making them available to the output document with the frameset. For more
details about the exsl:document instruction, see the EXSLT web site.

7.3.5 xdmp:dialect Attribute


You can add the attribute xdmp:dialect to any element in a stylesheet to control the dialect in
which expressions are evaluated, with a value of any valid dialect (for example, "1.0-ml" or
"1.0"). If no xdmp:dialect attribute is present, the default value is "1.0", which is
standards-compliant XSLT 2.0 XPath.

If you are using code shared with other stylesheets (especially stylesheets that might be used with
other XSLT processors), use care when setting the dialect to 1.0-ml, as it might have subtle
differences in the way expressions are evaluated.

For details about dialects, see “Overview of the XQuery Dialects” on page 7.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 86


MarkLogic Server XSLT in MarkLogic Server

7.3.6 Notes on Importing Stylesheets With <xsl:import>


XSLT includes the <xsl:import> instruction, which is used to import other stylesheets into a
stylesheet. The MarkLogic implementation of the <xsl:import> instruction is conformant to the
specification, but the <xsl:import> instruction can be complicated. For details on the
<xsl:import> instruction, see the XSLT specification or your favorite XSLT programming book.

Some of the important points to note about the <xsl:import> instruction are as follows:

• Any absolute URI references in the href attribute are resolved in the context of the current
MarkLogic Server database URIs. Relative paths are resolved relative to current module
in the App Server root. For details, see XQuery Library Modules and Main Modules in the
Application Developer’s Guide.
• Any code imported in an <xsl:import> instruction follows the rules of precedence for
XSLT imports. In general, that means that a stylesheet that imports has precedence over an
imported stylesheet.
• Any XQuery library modules imported into a styleheet follow the rules for XQuery
imports, not the rules for XSLT imports. Notably, only functions and variables in the
imported module are directly available to the stylesheet, not functions and variables that
the XQuery library might import. XQuery library module imports use the
<xdmp:import-module> extension instruction, as described in “Importing XQuery Function
Libraries to a Stylesheet” on page 84.

7.4 Invoking Stylesheets Directly Using the XSLT Rewriter


As described in “Invoking and Evaluating XSLT Stylesheets” on page 83, you invoke a stylesheet
from an XQuery program. To set up an HTTP App Server to invoke a stylesheet by directly
calling it from the App Server, you can set up a URL rewriter. For general information on using a
URL rewriter, see Creating an Interpretive XQuery Rewriter to Support REST Web Services in the
Application Developer’s Guide.

This section describes the sample URL rewriter for XSLT stylesheets and includes the following
parts:

• About the Sample Rewriter

• Setting Up the Sample Rewriter in Your HTTP App Server

7.4.1 About the Sample Rewriter


The sample XSLT rewriter consists of two files, both installed in the
<marklogic-dir>/Samples/xslt directory:

• xslt-invoker.xqy
• xslt-rewrite-handler.xqy

Once you set up the rewriter as described in the next section, URLs to the App Server of the form:

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 87


MarkLogic Server XSLT in MarkLogic Server

/filename.xsl?doc=/url-of-context-node.xml

will invoke the filename.xsl stylesheet and pass it the context node at the URI specified in the
doc request field.

It will also take URLs if the form:

/styled/url-of-context-node.xml?stylesheet=/stylesheet.xsl

will invoke the stylesheet at the path specified in the stylesheet request field passing in the context
node in the path after /styled (/url-of-context-node.xml in the above sample).

The following table describes what the request fields you pass translate to when you are using the
sample XSLT rewriter.

Request Field Description

doc Specifies the URI of the document to be passed into the stylesheet as the
context node. If there is no doc request field, then it defaults to a context
node of default.xml. If no document with the URI default.xml exists in
the database, then the rewriter will throw an exception.
stylesheet Used with paths that start with /styled. Specifies the path to the
stylesheet to invoke. If it is not present, uses the stylesheet at
default.xslt.

mode The name of the initial mode to pass into the stylesheet. If not present, no
mode is passed.
template The name of the initial template to pass into the stylesheet. If not present,
no template is passed in.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 88


MarkLogic Server XSLT in MarkLogic Server

7.4.2 Setting Up the Sample Rewriter in Your HTTP App Server


You can use the sample rewriter as-is or you can modify it to suit your needs. For example, if it
makes sense for your stylesheets, you can modify it to always pass a certain node as the context
node.

To use the sample XSLT rewriter, perform the following steps:

1. Copy the xslt-invoker.xqy and xslt-rewrite-handler.xqy modules from the


<marklogic-dir>/Samples/xslt directory to your App Server root. The files must be at the
top of the root of the App Server, not a subdirectory of the root. For example, if your root
is set to /space/my-app-server, you must copy the new files to
/space/my-app-server/xslt-invoker.xqy and
/space/my-app-server/xslt-rewrite-handler.xqy. If your root is in a modules database,
then you must load the 2 files as text document (with any needed permissions) with URIs
that begin with the App Server root.

2. In the Admin Interface, navigate to the HTTP App Server configuration for the App
Server in which want to directly invoke XSLT stylesheets.

3. On the HTTP Server Configuration page, find the url rewriter field (it is towards the
bottom of the page).

4. Enter /xslt-rewrite-handler.xqy into the url rewriter field.

5. Click OK.

Request against the App Server will now be automatically rewritten to directly invoke stylesheets
as described in the previous section.

7.5 XSLT, XQuery, or Both


Both XQuery and XSLT are Turing Complete programming languages; that is, in theory, you can
use either language to compute whatever you need to compute. XQuery and XSLT share the same
data model and share XPath 2.0, so there are a lot of commonalities between the two languages.

On some level, choosing which language to perform a specific task is one of style. Different
programmers have different styles, and so there is no “correct” answer to what to do in XQuery
and what to do in XSLT.

In practice, however, XSLT is very convenient for performing XML transformation. You can do
these transformations in XQuery too, and you can do them well in XQuery, but some
programmers find it more natural to write a transformation in XSLT.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 89


MarkLogic Server Application Programming in XQuery and XSLT

8.0 Application Programming in XQuery and XSLT


94

In MarkLogic Server, XQuery and XSLT are not only used to query XML, but are also used as
programming languages to create applications. They are especially powerful as a programming
languages to create web applications, as you can easily write XQuery and/or XSLT code that
outputs XHTML, which is the XML variant of HTML. This chapter describes some of the
language features that make XQuery and XSLT particularly useful as application programming
languages, and includes the following sections:

• Design Patterns

• Using Functions

• Search Functions

• Updates and Transactions

• HTTP App Server Functions

• Additional Resources

8.1 Design Patterns


For any programming language, there are design patterns that develop over time to perform
various tasks. In XQuery with MarkLogic Server, one design pattern developers have gravitated
toward is using MarkLogic Server to create single-tier applications, where an XQuery program
accesses the content in a database, prepares it for display to an application, and sends the results to
a client over an HTTP App Server.

Many of the extensions in the 1.0-ml enhanced XQuery dialect make building these types of
applications easier and more efficient. Extensions to the language such as try/catch are very useful
in building robust applications. For details on these extensions, see “MarkLogic Server Enhanced
XQuery Language” on page 15.

The Application Developer’s Guide lists many common design patterns in MarkLogic Server, and
the Search Developer’s Guide lists common design patterns for MarkLogic Server specific search
application functionality. These guides provide details about searches, lexicons, and many other
techniques developers use to build applications in MarkLogic Server.

8.2 Using Functions


Functions are a powerful way to encapsulate XQuery code. For an example of an XQuery
function, see “Declaring Functions” on page 42. This section covers the following aspects of
functions:

• Creating Reusable and Modular Code

• Recursive Functions

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 90


MarkLogic Server Application Programming in XQuery and XSLT

8.2.1 Creating Reusable and Modular Code


Functions provide a convenient way to modularize or componentize your XQuery code. When
you move some functionality into a function in a library module, it allows you to call that library
module and use any of its functions from any other XQuery module, allowing maximum code
reuse. You can separate the library modules any way that makes sense for your development
environment. For example, you can use a model-view-controller (MVC) approach where you
have a set of functions that are used to access the content, a set of functions used to display the
content in a user-interface, and a set of functions used to control the business logic of the
application (for example, workflow logic based on various events).

8.2.2 Recursive Functions


Using functions recursively (creating functions that call themselves) is a useful design pattern in
XQuery. Recursive functions are very convenient for iterating through an XML tree structure to
perform XML transformations from one structure to another.

Note that MarkLogic will apply tail call optimization to a recursive XQuery function if and only if
the function return type is untyped. For example:

(: Can be tail call optimized - no explicit return type :)


declare function my:func(
$param as xs:string
) {
...
};

(: Cannot be tail call optimized - explicitly returns node() :)


declare function my:func(
$param as xs:string
) as node() {
...
};

Recursive functions that are not tail call optimized create a new stack frame for each call and can
eventually cause a stack overflow if the call stack gets too deep. By contrast, tail call optimized
recursive functions use constant stack space.

For details on performing recursive transformations, see the Transforming XML Structures With a
Recursive typeswitch Expressionchapter of the Application Developer’s Guide.

You can also use XSLT to perform transformations. For more information about XSLT, see
“XSLT in MarkLogic Server” on page 83.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 91


MarkLogic Server Application Programming in XQuery and XSLT

8.3 Search Functions


MarkLogic Server includes functions to perform high-performance full-text search queries. The
cts:query constructors allow you to compose complex queries. The cts:search API returns
relevance-ranked, search-engine style queries. The cts:contains API can be used in XPath
predicates or other XQuery expressions. Both cts:search and cts:contains take the composable
cts:query APIs as a parameter, allowing you to perform full-text searches in any XQuery or
XSLT context, whether it is on content stored in a database or on content constructed in memory.

There are many index settings on the database configuration. The indexes speed up searches (both
XPath and cts:search) on documents in the database. The default index settings provide a good
mix of performance and economy of disk space, and the default settings work well in many
applications. If you want more index options, you can configure them at the database level.

For details on composing cts:query constructors, see Composing cts:query Expressions in the
Search Developer’s Guide. For the syntax of the various search built-in functions, see the
MarkLogic XQuery and XSLT Function Reference. For details on index options, see the Databases
and Text Indexing chapters of the Administrator’s Guide.

8.4 Updates and Transactions


MarkLogic Server is a transactional system that ensures data integrity. When you perform updates
on documents in a database, the system automatically locks any needed documents to ensure
those documents are not updated by any other concurrent transactions. If a query reads a
document, the system ensures that it the query reads a consistent view of the document throughout
the transaction.

There are XQuery/XSLT functions built into MarkLogic Server to create documents, update
documents, and delete documents in a database. These update built-in functions are used in
XQuery programs, so you can build complex logic (or whatever is required by your application)
into your programs that update content.

For details on transactions, see the Understanding Transactions in MarkLogic Server chapter in the
Application Developer’s Guide. For details on the update built-in functions, see the MarkLogic
XQuery and XSLT Function Reference.

8.5 HTTP App Server Functions


When you issue XQuery requests against a MarkLogic Server HTTP App Server, the requests are
processed over the HTTP protocol. MarkLogic Server provides XQuery built-in functions to
perform various HTTP server functions. Use these functions to HTTP-server related actions such
as adding an HTTP header, accessing the request object, and so on.

The App Server functions are extremely useful when you are creating complete applications that
return XHTML. For details about the signatures of the App Server functions, see the MarkLogic
XQuery and XSLT Function Reference.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 92


MarkLogic Server Application Programming in XQuery and XSLT

8.6 Additional Resources


This section lists some sources for additional XQuery resources. They include:

• MarkLogic Server Documentation

• XQuery Use Cases

• Other Publications

8.6.1 MarkLogic Server Documentation


In addition to this document, which describes the XQuery language implemented in MarkLogic
Server, the MarkLogic Server documentation also includes XQuery API documentation for all of
the XQuery-standard functions as well as the MarkLogic-defined XQuery functions. Included in
the API documentation are many useful XQuery code samples.

The other documents in the MarkLogic Server library describe various other aspects of the
product. In particular, the Application Developer’s Guide includes many useful XQuery design
patterns that work well with MarkLogic Server. For a description of MarkLogic Server
documentation, see the product documentation section of the MarkLogic Developer site
(http://developer.marklogic.com/).

8.6.2 XQuery Use Cases


MarkLogic Server includes an application that shows the XQuery Use Cases. The Use Cases have
been developed by the W3C XQuery Working Group and demonstrates how a significant number
of core tasks can be implemented using the XQuery language. The W3C describes the use cases in
the following document:

http://www.w3.org/TR/xquery-use-cases/

The Use Cases have a default XQuery dialect of 1.0, so if you want to run code in 1.0-ml, use an
XQuery version declaration in the prolog, as described in “Specifying the XQuery Dialect in the
Prolog” on page 13. The Getting Started with MarkLogic Server walks you through this process
of using the Use Cases application some detail.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 93


MarkLogic Server Application Programming in XQuery and XSLT

8.6.3 Other Publications


In addition to the MarkLogic Server documentation, there are many excellent third-party books
on XQuery. See the MarkLogic developer site for some recommendations
(http://developer.marklogic.com).

You can also look directly at the XQuery specification, although much of the specification is
geared more toward people who are implementing an XQuery processor rather than for people
who are writing applications in XQuery. Nevertheless, it is very useful to at least get some
familiarity with the following specifications:

• The current XQuery language recommendation (http://www.w3.org/TR/xquery/).


• The current recommendation for XQuery Functions and Operators
(http://www.w3.org/TR/xquery-operators/).
• The XML Schema standard—useful for both type definitions and to understand the
schema definitions that can be used in MarkLogic Server.

MarkLogic 10—May, 2019 XQuery and XSLT Reference Guide—Page 94


MarkLogic Server Technical Support

9.0 Technical Support


96

MarkLogic provides technical support according to the terms detailed in your Software License
Agreement or End User License Agreement.

We invite you to visit our support website at http://help.marklogic.com to access information on


known and fixed issues, knowledge base articles, and more. For licensed customers with an active
maintenance contract, see the Support Handbook for instructions on registering support contacts
and on working with the MarkLogic Technical Support team.

Complete product documentation, the latest product release downloads, and other useful
information is available for all developers at http://developer.marklogic.com. For technical
questions, we encourage you to ask your question on Stack Overflow.

MarkLogic 10
MarkLogic Server Technical Support

MarkLogic 10—May, 2019 Glossary, Copyright, and Support—Page 96


MarkLogic Server Copyright

10.0 Copyright
999

MarkLogic Server 10.0 and supporting products.


Last updated: February, 2021

Copyright © 2021 MarkLogic Corporation. All rights reserved.


This technology is protected by U.S. Patent No. 7,127,469B2, U.S. Patent No. 7,171,404B2, U.S.
Patent No. 7,756,858 B2, and U.S. Patent No 7,962,474 B2, US 8,892,599, and US 8,935,267.

The MarkLogic software is protected by United States and international copyright laws, and
incorporates certain third party libraries and components which are subject to the attributions,
terms, conditions and disclaimers set forth below.

For all copyright notices, including third-party copyright notices, see the Combined Product
Notices for your version of MarkLogic.

MarkLogic 10
MarkLogic Server Copyright

MarkLogic 10—May, 2019 Glossary, Copyright, and Support—Page 98

You might also like