W3C

XQuery 1.0 and XPath 2.0 Formal Semantics

W3C Proposed Recommendation 21 November 2006

This version:
http://www.w3.org/TR/2006/PR-xquery-semantics-20061121/
Latest version:
http://www.w3.org/TR/xquery-semantics/
Previous versions:
http://www.w3.org/TR/2006/CR-xquery-semantics-20060608/ http://www.w3.org/TR/2005/CR-xquery-semantics-20051103/ http://www.w3.org/TR/2005/WD-xquery-semantics-20050915/
Editors:
Denise Draper, Microsoft <denised@microsoft.com>
Peter Fankhauser (XML Query WG), Infonyte GmbH <fankhaus@infonyte.com>
Mary Fernández (XML Query WG), AT&T Labs - Research <mff@research.att.com>
Ashok Malhotra (XML Query and XSL WGs), Oracle Corporation <ashok.malhotra@oracle.com>
Kristoffer Rose (XSL WG), IBM T.J. Watson Research Center <krisrose@us.ibm.com>
Michael Rys (XML Query WG), Microsoft <mrys@microsoft.com>
Jérôme Siméon (XML Query WG), IBM T.J. Watson Research Center <simeon@us.ibm.com>
Philip Wadler (XML Query WG), University of Edinburgh <wadler@inf.ed.ac.uk>

This document is also available in these non-normative formats: XML and Recent revisions.


Abstract

This document defines formally the semantics of XQuery 1.0 [XQuery 1.0: An XML Query Language] and XPath 2.0 [XML Path Language (XPath) 2.0].

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This is a Proposed Recommendation. On 3 November 2005, this specification was published as a Candidate Recommendation, and a Call for Implementations was announced. On 08 June 2006, a revision was published in order to give visibility to the technical decisions that had been made in response to comments received since initial publication of the Candidate Recommendation.

Publication as a Proposed Recommendation does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress. This specification will remain a Proposed Recommendation until at least 31 December 2006.

This document was produced jointly by the XML Query Working Group and the XSL Working Group, both of which are part of the XML Activity.

This draft includes corrections and changes based on public comments recorded in the W3C public Bugzilla repository (http://www.w3.org/Bugs/Public/) used for issue tracking on the Candidate Recommendation. A list of substantive changes since the publication of the Candidate Recommendation of 03 November 2005 can be found in [G Revision Log].

This specification is designed to be referred to normatively from other specifications defining a host language for it; it is not intended to be implemented outside a host language. The implementability of this specification has been tested in the context of its normative inclusion in host languages defined by the XQuery 1.0 and XSLT 2.0 specifications; see those specifications for implementation reports.

The W3C Membership and other interested parties are invited to review the document and, through 31 December 2006, submit comments in W3C's public Bugzilla system (instructions can be found at http://www.w3.org/XML/2005/04/qt-bugzilla). If access to that system is not feasible, you may send your comments to the W3C XSLT/XPath/XQuery public comments mailing list, public-qt-comments@w3.org. It will be very helpful if you include the string [FS] in the subject line of your comment, whether made in Bugzilla or in email. Each Bugzilla entry and email message should contain only one comment. Archives of the comments and responses are available at http://lists.w3.org/Archives/Public/public-qt-comments/.

Members of the W3C Advisory Committee will find the appropriate review form for this document by consulting their list of current WBS questionnaires. Note that substantive technical comments were expected during the Last Call review period that ended 15 February 2004.

This document was produced by groups operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the XML Query Working Group and also maintains a public list of any patent disclosures made in connection with the deliverables of the XSL Working Group; those pages also include instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) with respect to this specification should disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1 Introduction
    1.1 Normative and Informative Sections
2 Preliminaries
    2.1 Introduction to the Formal Semantics
        2.1.1 Notations from grammar productions
        2.1.2 Notations for judgments
        2.1.3 Notations for environments
        2.1.4 Notations for inference rules
        2.1.5 Putting it together
    2.2 URIs, Namespaces, and Prefixes
    2.3 XML Values
        2.3.1 Formal values
        2.3.2 Examples of values
    2.4 The [XPath/XQuery] Type System
        2.4.1 XML Schema and the [XPath/XQuery] Type System
        2.4.2 Item types
        2.4.3 Content models
        2.4.4 Top level definitions
        2.4.5 Example of a complete Schema
    2.5 Functions and operators
3 Basics
    3.1 Expression Context
        3.1.1 Static Context
            3.1.1.1 Resolving QNames to Expanded QNames
        3.1.2 Dynamic Context
    3.2 Processing Model
        3.2.1 Processing model
        3.2.2 Normalization mapping rules
        3.2.3 Static typing judgment
        3.2.4 Dynamic evaluation judgment
    3.3 Error Handling
    3.4 Concepts
        3.4.1 Document Order
        3.4.2 Atomization
        3.4.3 Effective Boolean Value
        3.4.4 Input Sources
        3.4.5 URI Literals
    3.5 Types
        3.5.1 Predefined Schema Types
        3.5.2 Typed Value and String Value
        3.5.3 SequenceType Syntax
        3.5.4 SequenceType Matching
    3.6 Comments
    3.7 XML-defined Terminals
4 Expressions
    4.1 Primary Expressions
        4.1.1 Literals
        4.1.2 Variable References
        4.1.3 Parenthesized Expressions
        4.1.4 Context Item Expression
        4.1.5 Function Calls
    4.2 Path Expressions
        4.2.1 Steps
            4.2.1.1 Axes
            4.2.1.2 Node Tests
        4.2.2 Predicates
        4.2.3 Unabbreviated Syntax
        4.2.4 Abbreviated Syntax
    4.3 Sequence Expressions
        4.3.1 Constructing Sequences
        4.3.2 Filter Expressions
        4.3.3 Combining Node Sequences
    4.4 Arithmetic Expressions
    4.5 Comparison Expressions
        4.5.1 Value Comparisons
        4.5.2 General Comparisons
        4.5.3 Node Comparisons
    4.6 Logical Expressions
    4.7 Constructors
        4.7.1 Direct Element Constructors
            4.7.1.1 Attributes
            4.7.1.2 Namespace Declaration Attributes
            4.7.1.3 Content
            4.7.1.4 Boundary Whitespace
        4.7.2 Other Direct Constructors
        4.7.3 Computed Constructors
            4.7.3.1 Computed Element Constructors
            4.7.3.2 Computed Attribute Constructors
            4.7.3.3 Document Node Constructors
            4.7.3.4 Text Node Constructors
            4.7.3.5 Computed Processing Instruction Constructors
            4.7.3.6 Computed Comment Constructors
        4.7.4 In-scope Namespaces of a Constructed Element
    4.8 [For/FLWOR] Expressions
        4.8.1 FLWOR expressions
        4.8.2 For expression
        4.8.3 Let Expression
        4.8.4 Order By and Return Clauses
    4.9 Ordered and Unordered Expressions
    4.10 Conditional Expressions
    4.11 Quantified Expressions
    4.12 Expressions on SequenceTypes
        4.12.1 Instance Of
        4.12.2 Typeswitch
        4.12.3 Cast
        4.12.4 Castable
        4.12.5 Constructor Functions
        4.12.6 Treat
    4.13 Validate Expressions
        4.13.1 Validating an Element Node
        4.13.2 Validating a Document Node
    4.14 Extension Expressions
5 Modules and Prologs
    5.1 Version Declaration
    5.2 Module Declaration
    5.3 Boundary-space Declaration
    5.4 Default Collation Declaration
    5.5 Base URI Declaration
    5.6 Construction Declaration
    5.7 Ordering Mode Declaration
    5.8 Empty Order Declaration
    5.9 Copy-Namespaces Declaration
    5.10 Schema Import
    5.11 Module Import
    5.12 Namespace Declaration
    5.13 Default Namespace Declaration
    5.14 Variable Declaration
    5.15 Function Declaration
    5.16 Option Declaration
6 Conformance
    6.1 Static Typing Feature
        6.1.1 Static Typing Extensions
7 Additional Semantics of Functions
    7.1 Formal Semantics Functions
        7.1.1 The fs:convert-operand function
        7.1.2 The fs:convert-simple-operand function
        7.1.3 The fs:distinct-doc-order function
        7.1.4 The fs:distinct-doc-order-or-atomic-sequence function
        7.1.5 The fs:item-sequence-to-node-sequence function
        7.1.6 The fs:item-sequence-to-node-sequence-doc function
        7.1.7 The fs:item-sequence-to-untypedAtomic function
        7.1.8 The fs:item-sequence-to-untypedAtomic-PI function
        7.1.9 The fs:item-sequence-to-untypedAtomic-text function
        7.1.10 The fs:item-sequence-to-untypedAtomic-comment function
        7.1.11 The fs:apply-ordering-mode function
        7.1.12 The fs:to function
    7.2 Standard functions with specific static typing rules
        7.2.1 The fn:last context function
        7.2.2 The fn:position context function
        7.2.3 The fn:abs, fn:ceiling, fn:floor, fn:round, and fn:round-half-to-even functions
        7.2.4 The fn:boolean function
        7.2.5 The fn:collection and fn:doc functions
        7.2.6 The fn:data function
        7.2.7 The fn:distinct-values function
        7.2.8 The fn:unordered function
        7.2.9 The fn:error function
        7.2.10 The fn:min, fn:max, fn:avg, and fn:sum functions
        7.2.11 The fn:remove function
        7.2.12 The fn:reverse function
        7.2.13 The fn:subsequence function
        7.2.14 The op:union, op:intersect, and op:except operators
        7.2.15 The fn:insert-before function
        7.2.16 The fn:zero-or-one, fn:one-or-more, and fn:exactly-one functions
8 Auxiliary Judgments
    8.1 Judgments for accessing types
        8.1.1 Derives from
        8.1.2 Substitutes for
        8.1.3 Element and attribute name lookup (Dynamic)
        8.1.4 Element and attribute type lookup (Static)
        8.1.5 Extension
        8.1.6 Mixed content
        8.1.7 Type adjustment
        8.1.8 Builtin attributes
        8.1.9 Type expansion
        8.1.10 Union interpretation of derived types
    8.2 Judgments for step expressions and filtering
        8.2.1 Principal Node Kind
        8.2.2 Auxiliary judgments for axes
            8.2.2.1 Static semantics of axes
                8.2.2.1.1 Inference rules for all axes
                8.2.2.1.2 Inference rules for the self axis
                8.2.2.1.3 Inference rules for the child axis
                8.2.2.1.4 Inference rules for the attribute axis
                8.2.2.1.5 Inference rules for the parent axis
                8.2.2.1.6 Inference rules for the namespace axis
                8.2.2.1.7 Inference rules for the descendant axis
                8.2.2.1.8 Inference rules for the descendant-or-self axis
                8.2.2.1.9 Inference rules for the ancestor axis
                8.2.2.1.10 Inference rules for the ancestor-or-self axis
            8.2.2.2 Dynamic semantics of axes
        8.2.3 Auxiliary judgments for node tests
            8.2.3.1 Static semantics of node tests
                8.2.3.1.1 Name Tests
                8.2.3.1.2 Kind Tests
            8.2.3.2 Dynamic semantics of node tests
                8.2.3.2.1 Name Tests
                8.2.3.2.2 Kind Tests
    8.3 Judgments for type matching
        8.3.1 Matches
        8.3.2 Subtyping (<:)
    8.4 Judgments for FLWOR and other expressions on sequences
    8.5 Judgments for function calls
        8.5.1 Type promotion
    8.6 Judgments for validation modes and contexts
        8.6.1 Elements in validation mode

Appendices

A Normalized core and formal grammars
    A.1 Core BNF
    A.2 Formal BNF
B Index of judgments
C Functions and Operators
    C.1 Functions and Operators used in the Formal Semantics
    C.2 Mapping of Overloaded Internal Functions
D Importing Schemas
    D.1 Introduction
        D.1.1 Features
        D.1.2 Organization
        D.1.3 Main mapping rules
        D.1.4 Special attributes
            D.1.4.1 use, default, and fixed
            D.1.4.2 minOccurs, maxOccurs, minLength, maxLength, and length
            D.1.4.3 mixed
            D.1.4.4 nillable
            D.1.4.5 substitutionGroup
        D.1.5 Anonymous type names
    D.2 Schemas as a whole
        D.2.1 Schema
        D.2.2 Include
        D.2.3 Redefine
        D.2.4 Import
    D.3 Attribute Declarations
        D.3.1 Global attributes declarations
        D.3.2 Local attribute declarations
    D.4 Element Declarations
        D.4.1 Global element declarations
        D.4.2 Local element declarations
    D.5 Complex Type Definitions
        D.5.1 Global complex type
        D.5.2 Local complex type
        D.5.3 Complex type with simple content
        D.5.4 Complex type with complex content
    D.6 Attribute Uses
    D.7 Attribute Group Definitions
        D.7.1 Attribute group definitions
        D.7.2 Attribute group reference
    D.8 Model Group Definitions
    D.9 Model Groups
        D.9.1 All groups
        D.9.2 Choice groups
        D.9.3 Sequence groups
    D.10 Particles
        D.10.1 Element reference
        D.10.2 Group reference
    D.11 Wildcards
        D.11.1 Attribute wildcards
        D.11.2 Element wildcards
    D.12 Identity-constraint Definitions
    D.13 Notation Declarations
    D.14 Annotation
    D.15 Simple Type Definitions
        D.15.1 Global simple type definition
        D.15.2 Local simple type definition
        D.15.3 Simple type content
E References
    E.1 Normative References
    E.2 Non-normative References
    E.3 Background References
F Auxiliary Judgments for Validation (Non-Normative)
    F.1 Judgments for the validate expression
        F.1.1 Type resolution
        F.1.2 Interleaving
        F.1.3 Attribute filtering
        F.1.4 Erasure
            F.1.4.1 Simply erases
            F.1.4.2 Erases
        F.1.5 Annotate
            F.1.5.1 Simply annotate
            F.1.5.2 Nil-annotate
            F.1.5.3 Annotate
G Revision Log (Non-Normative)
    G.1 15 September 2005
    G.2 03 November 2005 (CR Draft)
    G.3 09 June 2006
    G.4 16 June 2006


1 Introduction

This document defines the formal semantics of XQuery 1.0 and XPath 2.0. The present document is part of a set of documents that together define the XQuery 1.0 and XPath 2.0 languages:

The scope and goals for the [XPath/XQuery] language are discussed in the charter of the W3C [XSL/XML Query] Working Group and in the [XPath/XQuery] requirements [XML Query 1.0 Requirements].

This document defines the semantics of [XPath/XQuery] by giving a precise formal meaning to each of the expressions of the [XPath/XQuery] specification in terms of the [XPath/XQuery] data model. This document assumes that the reader is already familiar with the [XPath/XQuery] language. This document defines the formal semantics for XPath 2.0 only when the XPath 1.0 backward compatibility rules are not in effect.

Two important design aspects of [XPath/XQuery] are that it is functional and that it is typed. These two aspects play an important role in the [XPath/XQuery] Formal Semantics.

[XPath/XQuery] is a functional language. [XPath/XQuery] is built from expressions, rather than statements. Every construct in the language (except for the XQuery query prolog) is an expression and expressions can be composed arbitrarily. The result of one expression can be used as the input to any other expression, as long as the type of the result of the former expression is compatible with the input type of the latter expression with which it is composed. Another characteristic of a functional language is that variables are always passed by value, and a variable's value cannot be modified through side effects.

[XPath/XQuery] is a typed language. Types can be imported from one or more XML Schemas that describe the input documents and the output document, and the [XPath/XQuery] language can then perform operations based on these types. In addition, [XPath/XQuery] supports static type analysis. Static type analysis infers the output type of an expression based on the type of its input expressions. In addition to inferring the type of an expression for the user, static typing allows early detection of type errors, and can be used as the basis for certain classes of optimization. The [XPath/XQuery] type system captures most of the features of [Schema Part 1], including global and local element and attribute declarations, complex and simple type definitions, named and anonymous types, derivation by restriction, extension, list and union, substitution groups, and wildcard types. It does not model uniqueness constraints and facet constraints on simple types.

This document is organized as follows. [2 Preliminaries] introduces the notations used to define the [XPath/XQuery] Formal Semantics. These include the formal notations for values in the [XPath/XQuery] data model and for types in XML Schema. The next three sections: [3 Basics], [4 Expressions], and [5 Modules and Prologs] have the same structure as the corresponding sections in the [XQuery 1.0: An XML Query Language] and [XML Path Language (XPath) 2.0] documents. This allows the reader to quickly find the formal definition of a particular language construct. [3 Basics] defines the semantics for basic [XPath/XQuery] concepts, and [4 Expressions] defines the dynamic and static semantics of each [XPath/XQuery] expression. [5 Modules and Prologs] defines the semantics of the [XPath/XQuery] prolog. [7 Additional Semantics of Functions] defines the static semantics of several functions in [Functions and Operators] and gives the dynamic and static semantics of several supporting functions used in this document. The remaining sections, [8 Auxiliary Judgments] and [D Importing Schemas], contain material that supports the formal semantics of [XPath/XQuery]. [8 Auxiliary Judgments] defines formal judgments that relate data model values to types, that relate types to types, and that support the formal definition of validation. These judgments are used in the definition of expressions in [4 Expressions]. Lastly, [D Importing Schemas], specifies how XML Schema documents are imported into the [XPath/XQuery] type system and relates XML Schema types to the [XPath/XQuery] type system.

1.1 Normative and Informative Sections

Certain aspects of language processing are described in this specification as implementation-defined or implementation-dependent.

  • [Definition: Implementation-defined indicates an aspect that may differ between implementations, but must be specified by the implementor for each particular implementation.]

  • [Definition: Implementation-dependent indicates an aspect that may differ between implementations, is not specified by this or any W3C specification, and is not required to be specified by the implementor for any particular implementation.]

A language aspect described in this specification as implementation-defined or implementation dependent may be further constrained by the specifications of a host language in which XPath or XQuery is embedded.

This document contains the normative static semantics of [XPath/XQuery]. The static semantics rules in [3 Basics], [4 Expressions], [5 Modules and Prologs], and [7 Additional Semantics of Functions] are normative. [3.1.1 Static Context] is normative, because it defines the static context used in the static typing rules. [8 Auxiliary Judgments] is normative, because it contains all the judgments necessary for defining SequenceType Matching.

The dynamic semantics of [XPath/XQuery] are normatively defined in [XQuery 1.0: An XML Query Language] and [XML Path Language (XPath) 2.0]. In this document, the dynamic semantic rules in [3 Basics], [4 Expressions], and [5 Modules and Prologs], the examples, and the material labeled as "Note" are provided for explanatory purposes and are not normative.

The mapping rules from XML Schema to the XQuery type system provided in [D Importing Schemas], and the formal semantics of XML Schema validation in [F Auxiliary Judgments for Validation] are informative and do not handle every feature of XML Schema.

2 Preliminaries

This section provides the background necessary to understand the Formal Semantics, introduces the notations that are used, and explains its relationship to other documents.

2.1 Introduction to the Formal Semantics

Why a Formal Semantics? The goal of the formal semantics is to complement the [XPath/XQuery] specification ([XQuery 1.0: An XML Query Language] and [XML Path Language (XPath) 2.0]), by defining the meaning of [XPath/XQuery] expressions with mathematical rigor.

A rigorous formal semantics clarifies the intended meaning of the English specification, ensures that no corner cases are left out, and provides a reference for implementation.

Why use formal notations? Rigor is achieved by the use of formal notations to represent [XPath/XQuery] objects such as expressions, XML values, and XML Schema types, and by the systematic definition of the relationships between those objects to reflect the meaning of the language. In particular, the dynamic semantics relates [XPath/XQuery] expressions to the XML value to which they evaluate, and the static semantics relates [XPath/XQuery] expressions to the XML Schema type that is inferred for that expression.

The Formal Semantics uses several kinds of formal notations to define the relationships between [XPath/XQuery] expressions, XML values, and XML Schema types. This section introduces the notations for judgments, inference rules, and mapping rules as well as the notation for environments, which implement the dynamic and static contexts. The reader already familiar with these notations can skip this section and continue with [2.3 XML Values].

2.1.1 Notations from grammar productions

Grammar productions are used to describe "objects" (values, types, [XPath/XQuery] expressions, etc.) manipulated by the Formal Semantics. The Formal Semantics makes use of several kinds of grammar productions: productions from the [XPath/XQuery] grammar itself, productions for a subset of the [XPath/XQuery] language called the XQuery Core which is used throughout this document, and other productions used for formal specification only such as for the XQuery type system.

XQuery grammar productions describe the XQuery language and expressions. XQuery productions are identified by a number, which corresponds to their number in the [XQuery 1.0: An XML Query Language] document, and are marked with "(XQuery)". For instance, the following production describes FLWOR expressions in XQuery.

[For/FLWOR] Expressions
[33 (XQuery)]    FLWORExprXQ    ::=    (ForClause | LetClause)+ WhereClause? OrderByClause? "return" ExprSingle

For the purpose of this document, the differences between the XQuery 1.0 and the XPath 2.0 grammars are mostly irrelevant. By default, this document uses XQuery 1.0 grammar productions. Whenever the grammar for XPath 2.0 differs from the one for XQuery 1.0, the corresponding XPath 2.0 productions are also given. XPath productions are identified by a number, which corresponds to their number in [XML Path Language (XPath) 2.0], and are marked with "(XPath)". For instance, the following production describes for expressions in XPath.

[For/FLWOR] Expressions
[4 (XPath)]    ForExprXP    ::=    SimpleForClause "return" ExprSingle

XQuery Core grammar productions describe the XQuery Core. The Core grammar is given in [A Normalized core and formal grammars]. Core productions are identified by a number, which corresponds to their number in [A Normalized core and formal grammars], and are marked with "(Core)". For instance, the following production describes the simpler form of the "FLWOR" expression in the XQuery Core.

Core FLWOR Expressions
[24 (Core)]    FLWORExpr    ::=    (ForClause | LetClause) "return" ExprSingle

The Formal Semantics manipulates "objects" (values, types, expressions, etc.) for which there is no existing grammar production in the [XQuery 1.0: An XML Query Language] document. In these cases, specific grammar productions are introduced. Notably, additional productions are used to describe values in the [Data Model], and to describe the [XPath/XQuery] type system. Formal Semantics productions are identified by a number, and are marked by "(Formal)". For instance, the following production describes global type definitions in the [XPath/XQuery] type system.

Type Definitions
[39 (Formal)]    Definition    ::=    ("define" "element" ElementName OptSubstitution OptNillable TypeReference)
| ("define" "attribute" AttributeName TypeReference)
| ("define" "type" TypeName TypeDerivation)

Note that grammar productions that are specific to the Formal Semantics (i.e., marked with "(Formal)") are not part of [XPath/XQuery]. They are not accessible to the user and are only used in the course of defining the languages' semantics.

Grammar non-terminals are used extensively in this document to represent objects in judgments (see the next section). As a convenience, non-terminals used in judgments link to the appropriate grammar production.

2.1.2 Notations for judgments

The basic building block of the formal specification is called a judgment. A judgment expresses whether a property holds or not.

For example:

Notation

The judgment

Object is a positive integer

holds if the object Object is a positive integer.

A judgment may hold (if it is true) or not hold (if it is false). For instance '1 is a positive integer' holds and '-1 is a positive integer' does not hold.

Notation

Here are two other example judgments.

The judgment

Expr => Value

holds if the expression Expr yields (or evaluates to) the value Value.

The judgment

Expr : Type

holds if the expression Expr has the type Type.

Most other judgments used in this document are short English sentences intended to reflect their meaning. For instance, the judgment

Axis has principal PrincipalNodeKind

holds if PrincipalNodeKind is the principal node kind for the axis Axis.

A judgment can contain symbols and patterns.

Symbols are purely syntactic and are used to write the judgment itself. Symbols are chosen to reflect a judgment's meaning, and are written in bold fonts. For example, 'is a positive integer', '=>' and ':' are symbols, the second and third of which should be read "yields", and "has type" respectively.

Patterns are used to represent objects, constructed from a given grammar production. In patterns, italicized words usually correspond to non-terminals in the grammar. The name of those non-terminals is significant, and may be instantiated only to an "object" (a value, a type, an expression, etc.) that can be substituted legally for that non-terminal. For example, 'Expr' is a pattern that stands for every [XPath/XQuery] expressions, 'Expr1 + Expr2' is a pattern that stands for every addition expression, 'element a { Value }' is a pattern that stands for every value in the [XPath/XQuery] data model that is an 'a' element.

Non-terminals in a pattern may appear with subscripts (e.g. Expr1, Expr2) to distinguish different instances of the same sort of pattern. In some cases, non-terminals in a pattern may have a name that is not exactly the name of that non terminal, but is based on it. For instance, a BaseTypeName is a pattern that stands for a type name, as would TypeName, or TypeName2. This usage is limited, and only occurs to improve the readability of some of the inference rules.

When instantiating the judgment, each pattern must be instantiated to an appropriate sort of "object" (value, type, expression, etc). For example, '3 => 3' and '$x+0 => 3' are both instances of the judgment 'Expr => Value'. Note that in the first judgment, '3' corresponds to both the expression '3' (on the left-hand side of the => symbol) and to the value '3' (on the right-hand side of the => symbol).

In some cases, inference rules may need to use the fact that a certain judgment does not hold. not(Judgment) holds if and only if Judgment does not hold.

In some cases, a pattern may be instantiated to a value within a finite set of pre-determined values. We may write that set of possible values using the in judgment. For instance, the judgment

Color in { blue, green }

holds if the pattern Color has either the value blue or the value green.

In some cases, a judgment may use the "=" sign to indicate that a given value is equal to another value, or that a pattern is equal to a given value. For instance, the judgment

Color = blue

holds if the pattern Color has the value blue.

An index to all the judgments used in this specification is provided in [B Index of judgments].

2.1.3 Notations for environments

An environment component is a dictionary that maps a symbol (e.g., a function name or a variable name) to an "object" (e.g., a function body, a type, a value). One can access information in an environment component or update it.

If "envComp" is an environment component, then "envComp(symbol)" denotes the "object" to which symbol is mapped. The notation is intentionally similar to function application, because an environment component can be considered a function from the argument symbol to the "object" to which the symbol is mapped.

This document uses environments that group related environment components. If "env" is an environment containing the environment component "envComp", that environment component is denoted "env.envComp". The value that symbol is mapped to in that environment component is denoted "env.envComp(symbol)".

The two main environments used in the Formal Semantics are: a dynamic environment (dynEnv), which models the [XPath/XQuery] dynamic context, and a static environment (statEnv), which models the [XPath/XQuery] static context. Both are defined in [3.1 Expression Context].

For example, dynEnv.varValue denotes the dynamic environment component that maps variables to values and dynEnv.varValue(Variable) denotes the value of the variable Variable in the dynamic context.

Environments are used in a judgment to capture some of the context in which the judgment is computed, and most judgments are computed assuming that some environment is given. This assumption is denoted by prefixing the judgment with "env |-". The "|-" symbol is called a "turnstile" and is used in almost all inference rules.

For instance, the judgment

dynEnv |-  Expr => Value

is read as: Assuming the dynamic environment dynEnv, the expression Expr yields the value Value.

Environments can be updated, using the following notation:

  • "env + envComp(symbol => object) " denotes the new environment that is identical to env except that the environment component envComp has been updated to map symbol to object. The notation symbol => object indicates that symbol is mapped to object in the new environment.

  • In case the environment component contains only a constant value (e.g., the ordering mode which can only be either ordered or unordered), the following notation is used to set its value. "env + envComp( object ) ".

  • The following shorthand is also allowed: "env + envComp( symbol1 => object1 ; ... ; symboln => objectn ) " in which each symbol is mapped to a corresponding object in the new environment.

    This notation is equivalent to nested updates, as in " (env + envComp( symbol1 => object1) + ... ) + env(symboln => objectn)".

Updating an environment creates a copy of the original environment and overrides any previous binding that might exist for the same name and the same component in that environment. Updating the environment is used to capture the scope of a symbol (e.g., for variables, namespace prefixes, etc). For instance, in the following expression

  let $x := 1 return
  let $x := $x + 2 return
  $x - 3

each let expression changes the dynamic context by binding a new variable to a new value. Each different context is represented by a different environment. The original environment, in which the expression 1 is evaluated, does not contain any binding for variable $x. This environment is updated a first time with a binding of variable $x to the value 1, and this environment is used for the evaluation of the expression $x + 2. Then it is updated a second time with a binding of variable $x to the value 3, and this environment is used for the evaluation of the expression $x - 3.

Also, note that there are no operations to remove entries from environments. This is never necessary as updating an environment effectively creates a new extended copy of the original environment, leaving the original environment accessible wherever it is in scope along with the updated copy.

2.1.4 Notations for inference rules

Inference rules are used to specify how to infer whether a given judgment holds or not. Inference rules express the logical relation between judgments and describe how complex judgments can be concluded from simpler premise judgments.

A logical inference rule is written as a collection of premises and a conclusion, written respectively above and below a dividing line, as follows:

premise1 ... premisen

conclusion

All premises and the conclusion are judgments. From a logical point of view, an inference rule is a deduction that if the premises hold, then the conclusion holds as well. In that sense, the previous inference rule has a similar meaning as the following logical statement.

IF premise1

AND ...

AND premisen

THEN conclusion

Here is a simple example of inference rule, which uses specific instances of the example judgment 'Expr => Value' from above:

$x => 0      3 => 3

$x + 3 => 3

This inference rule expresses the following property: if the variable expression '$x' yields the value '0', and the literal expression '3' yields the value '3', then the expression '$x + 3' yields the value '3'.

An inference rule may have no premises above the line, which means that the expression below the line always holds. For instance:


3 => 3

This inference rule expresses the following property: evaluating the literal expression '3' always yields the value '3'.

The two above rules are expressed in terms of specific expressions and values, but usually rules are more abstract. That is, the judgments are not fully instantiated. Here is a rule that says that for any variable $VarName that yields the integer value Integer, adding '0' yields the same integer value:

$VarName => Integer

$VarName + 0 => Integer

Each occurrence of a given pattern in a particular inference rule must be instantiated to the same "object" within the entire rule. This means that, in the context of a particular instantiation of a rule, one can talk about "the value of $VarName" instead of the value bound to the first (second, etc) occurrence of $VarName.

Here is an example of a rule occurring later in this document.

statEnv |-  Expr1 : Type1      statEnv |-  Expr2 : Type2

statEnv |-  Expr1 , Expr2 : Type1, Type2

This rule is read as follows: if two expressions Expr1 and Expr2 are known to have the static types Type1 and Type2 (the two premises above the line), then it is the case that the sequence expression "Expr1 , Expr2" has the static type "Type1, Type2", which is the sequence of types Type1 and Type2. Note that this inference rule does not modify the static environment.

The following rule defines the static semantics of a "let" expression. The binding of the new variable is captured by an update to the varType component of the original static environment.

statEnv |-  VarName of var expands to expanded-QName
statEnv |-  Expr1 : Type1      statEnv + varType(expanded-QName => Type1)  |-  Expr2 : Type2

statEnv |-  let $VarName := Expr1 return Expr2 : Type2

This rule is read as follows: First, because the variable is a QName, it is first expanded into an expanded QName. Second, the type Type1 for the "let" input expression Expr1 is computed. Then the "let" variable with expanded name, expanded-QName with type Type1 is added into the varType component of the static environment statEnv. Finally, the type Type2 of Expr2 is computed in that new environment.

In some cases, ellipses may be used in inference rules to handle an arbitrary number of judgments. In those cases, some of the patterns may have indices as subscript. If the same index is used several times within the same rule, the number of judgment in each case must be the same. For instance, the following rule holds for any number of expressions, from Expr1 to Exprn, with the same number of types Type1 to Typen.

statEnv |-  QName of func expands to expanded-QName
statEnv |-  Expr1 : Type1
...
statEnv |-  Exprn : Typen
statEnv  |-  expanded-QName(Type1,...,Typen) : Type

statEnv  |-  QName (Expr1,...,Exprn) : Type

This inference rule is equivalent to having an unbounded number of rules, the first of which has 1 judgment, the second of which has 2 judgments, etc. For instance, the above rule holds if and only if one of the following rules hold.

statEnv |-  QName of func expands to expanded-QName
statEnv |-  Expr1 : Type1
statEnv  |-  expanded-QName(Type1) : Type

statEnv  |-  QName (Expr1) : Type

or

statEnv |-  QName of func expands to expanded-QName
statEnv |-  Expr1 : Type1
statEnv |-  Expr2 : Type2
statEnv  |-  expanded-QName(Type1,Type2) : Type

statEnv  |-  QName (Expr1,Expr2) : Type

etc.

When ellipses are used, the value for the index always ranges from 1 to an arbitrary number n.

2.1.5 Putting it together

In isolation, each inference rule describes a fragment of the semantics for a given judgment. Put together, inference rules describe possible inferences that can be used to decide whether a particular judgment holds.

For a given judgment, if that judgment can be inferred to be true by applying any sequence of inferences based on premises which are known to be true, the inference succeeds. In most cases, the inference will proceed by proving intermediate judgments, following the consequences from one judgment to the next by applying successive inference rules.

Such inference is a mechanism which can be used to describe both static type analysis and dynamic evaluation. More specifically, performing static typing consists in proving that the following judgment holds for a given expression Expr.

statEnv |-  Expr : Type

If the judgment holds for a given type Type, this type is a possible static type for the expression. If there exists no type for which this judgment holds, then static typing fails and a static type error is returned to the user.

Consider the following expression.

  fn:count((1,2,3))

Using the static typing rules given for expressions in the rest of this document, one can deduce that the expression is of type xs:integer through the following inference.

  statEnv |- 1 : xs:integer  (from typing of literals)
  statEnv |- 2 : xs:integer  (from typing of literals)
  --------------------------------------------------- (sequence)
    statEnv |- 1,2 : xs:integer, xs:integer
    statEnv |- 3 : xs:integer
    ----------------------------------------------------- (sequence)
    statEnv |- 1,2,3 : xs:integer, xs:integer, xs:integer

    declare function fn:count($x as item()*) as xs:integer
    statEnv |- xs:integer,xs:integer,xs:integer <: item()*
    ---------------------------------------------------------- (function call)
    statEnv |- fn:count((1,2,3)) : xs:integer

Conversly, consider the following expression.

  fn:nilled((1,2,3))

Using the static typing rules given for expressions in the rest of this document, one can apply inference rules up to the following point.

    ....
    ----------------------------------------------------- (sequence)
    statEnv |- 1,2,3 : xs:integer, xs:integer, xs:integer

However, there is no rule that can infer the type of fn:nilled((1,2,3)), because the static typing rules for function calls will only hold if the type of the function parameters is a subtype of the expected type. However, here (xs:integer,xs:integer,xs:integer) is not a node type, which is the expected type for the function fn:nilled.

Note that in some cases, the inference can only proceed through the appropriate changes to the environment. For instance, consider the following expression.

  let $x := 1 return ($x,$x)

Using the static typing rules given for expressions in the rest of this document, one can deduce that the expression is of type (xs:integer,xs:integer) through the following inference.

statEnv0.varType = ()

  -------------------------- (literal)
  statEnv0 |- 1 : xs:integer

statEnv1 = statEnv0 + varType($x => xs:integer)

     statEnv1.varType($x) = xs:integer
     --------------------------------- (variable reference)
     statEnv1 |- $x : xs:integer

     statEnv1.varType($x) = xs:integer
     --------------------------------- (variable reference)
     statEnv1 |- $x : xs:integer

     ------------------------------------------- (sequence)
     statEnv1 |- ($x,$x) : xs:integer,xs:integer

  -------------------------------------------------------------- (let)
  statEnv0 |- let $x := 1 return ($x,$x) : xs:integer,xs:integer

This example illustrates how each rule is applied to individual sub-expressions, and how the environment is used to maintain the relevant context information.

2.2 URIs, Namespaces, and Prefixes

The Formal Semantics does not formally specify the adjustment of relative URIs according to a base URI. All URIs used in this document are assumed to be absolute URIs.

The Formal Semantics uses the following namespace prefixes.

  • fn: for functions and operators from the [Functions and Operators] document.

  • xs: for XML Schema components and built-in types.

These prefixes are assumed to be bound to the appropriate URIs.

In addition, the Formal Semantics uses the following special prefixes for specification purposes.

These prefixes are always italicized to emphasize that the corresponding functions, variables, and types are abstract: they are not and cannot be made accessible in [XPath/XQuery]. None of these special prefixes are given an explicit URI, but they behave as if they had one for the purposes of namespace resolution.

2.3 XML Values

The [XPath/XQuery] language is defined over values of the [XPath/XQuery] data model. The [XPath/XQuery] data model is defined normatively in [Data Model]. We define the formal notation that is used in this document to describe and manipulate values in inference rules. Formal values are used for specification purposes only and are not exposed to the [XPath/XQuery] user.

This section gives the grammar for formal values, along with a summary of the corresponding data model properties. In the context of this document, all constraints on values that are specified in [Data Model] are assumed to hold.

2.3.1 Formal values

A value is a sequence of zero or more items. An item is either an atomic value or a node.

An atomic value is a value in the value space of an atomic type, labeled with the name of that atomic type. An atomic type is either a primitive or derived atomic type according to XML Schema [Schema Part 2], xs:untypedAtomic, or xs:anyAtomicType.

A node is either an element, an attribute, a document, a text, a comment, or a processing-instruction node.

Element nodes have a type annotationXQ and contain a complex value or a simple value. Attribute nodes have a type annotationXQ and contain a simple value. Text nodes always contain one string value of type xs:untypedAtomic, therefore the corresponding type annotation is omitted in the formal notation of a text node. Document nodes do not have a type annotation and contain a sequence of element, text, comment, or processing-instruction nodes.

A simple value is a sequence of atomic values.

A complex value is a sequence of attribute nodes followed by a sequence of element, text, comment, or processing-instruction nodes.

A type annotationXQ can be either the QName of a declared type or an anonymous type. An anonymous type corresponds to an XML Schema type for which the schema writer did not provide a name. Anonymous type names are not visible to the user, but are generated during schema validation and used to annotate nodes in the data model. By convention, anonymous type names are written using the fs: Formal Semantics prefix: fs:anon0, fs:anon1, etc.

Formal values are defined by the following grammar.

Values
[7 (Formal)]    Value    ::=    Item
| (Value "," Value)
| ("(" ")")
[21 (Formal)]    Item    ::=    NodeValue
| AtomicValue
[22 (Formal)]    AtomicValue    ::=    AtomicValueContent TypeAnnotation?
[1 (Formal)]    AtomicValueContent    ::=    String
| Boolean
| Decimal
| Float
| Double
| Duration
| DateTime
| Time
| Date
| GYearMonth
| GYear
| GMonthDay
| GDay
| GMonth
| HexBinary
| Base64Binary
| AnyURI
| expanded-QName
| NOTATION
[2 (Formal)]    TypeAnnotation    ::=    "of" "type" TypeName
[9 (Formal)]    ElementValue    ::=    "element" ElementName "nilled"? TypeAnnotation? "{" Value "}" ("{" NamespaceBindings "}")?
[10 (Formal)]    AttributeValue    ::=    "attribute" AttributeName TypeAnnotation? "{" SimpleValue "}"
[8 (Formal)]    SimpleValue    ::=    AtomicValue
| (SimpleValue "," SimpleValue)
| ("(" ")")
[11 (Formal)]    DocumentValue    ::=    "document" "{" Value "}"
[13 (Formal)]    CommentValue    ::=    "comment" "{" String "}"
[14 (Formal)]    ProcessingInstructionValue    ::=    "processing-instruction" NCName "{" String "}"
[12 (Formal)]    TextValue    ::=    "text" "{" String "}"
[20 (Formal)]    NodeValue    ::=    ElementValue
| AttributeValue
| DocumentValue
| TextValue
| CommentValue
| ProcessingInstructionValue
[3 (Formal)]    ElementName    ::=    QName
[6 (Formal)]    AttributeName    ::=    QName
[23 (Formal)]    TypeName    ::=    QName
[15 (Formal)]    NamespaceBindings    ::=    NamespaceBinding ("," NamespaceBinding)*
[17 (Formal)]    NamespaceBinding    ::=    "namespace" NCName "{" AnyURI "}"

Notation

In the production for AtomicValueContent, each symbol in the right-hand side corresponds to one of the primitive datatypes. For example, String corresponds to xs:string, and Boolean corresponds to xs:boolean. (The mapping is obvious, except that "expanded-QName" corresponds to xs:QName) Although there are no explicit productions for these symbols, we assume that each is a non-terminal that derives a set of syntactic objects, each of which corresponds to a value in the value space of the corresponding datatype. For instance, the non-terminal String derives a set of syntactic objects, which appear in examples as "", "a", "John", etc.; each one corresponds to a string value in the xs:string value space. For familiarity, these objects have been given the same appearance as StringLiterals from the XQuery and Core grammars; however, these are formal objects, with a distinct role in the FS.

Element (resp. attributes) without type annotations, are assumed to have the type annotation xs:anyType (resp. xs:anySimpleType). Atomic values without type annotations, are assumed to have a type annotation which is the base type for the corresponding value. For instance, "Hello, World!" is equivalent to "Hello, World!" of type xs:string.

Untyped elements (e.g., from well-formed documents) have the type annotationXQ xs:untyped, untyped attributes have the type annotationXQ xs:untypedAtomic, and untyped atomic values have the type annotationXQ xs:untypedAtomic.

An element has an optional "nilled" marker. This marker is present only if the element has been validated against an element type in the schema which is "nillable", and the element has no content and an attribute xsi:nil set to "true".

An element also has a sequence of namespace bindings, which are the set of in-scope namespaces for that element. Each namespace binding is a prefix, URI pair. Elements without namespace bindings are assumed to have an empty set of in-scope namespaces.

Note:

In [XPath], the in-scope namespaces of an element node are represented by a collection of namespace nodes arranged on a namespace axis, which is optional and deprecated in [XML Path Language (XPath) 2.0]. XQuery does not support the namespace axis and does not represent namespace bindings in the form of nodes.

2.3.2 Examples of values

A well-formed document

  <fact>The cat weighs <weight units="lbs">12</weight> pounds.</fact>

In the absence of a Schema, this document is represented as

  element fact of type xs:untyped {
    text { "The cat weighs " },
    element weight of type xs:untyped {
      attribute units of type xs:untypedAtomic {
        "lbs" of type xs:untypedAtomic
      }
      text { "12" }
    },
    text { " pounds." }
  }

A document before and after validation.

  <weight xsi:type="xs:integer">42</weight>

The formal model for values can represent values before and after validation. Before validation, this element is represented as:

  element weight of type xs:untyped {
    attribute xsi:type of type xs:untypedAtomic {
      "xs:integer" of type xs:untypedAtomic
    },
    text { "42" }
  }

After validation, this element is represented as:

  element weight of type xs:integer {
    attribute xsi:type of type xs:QName {
      "xs:integer" of type xs:QName
    },
    42 of type xs:integer
  }

An element with a list type

  <sizes>1 2 3</sizes>

Before validation, this element is represented as:

  element sizes of type xs:untyped {
    text { "1 2 3" }
  }

Assume the following Schema.

  <xs:element name="sizes" type="sizesType"/>
  <xs:simpleType name="sizesType">
    <xs:list itemType="sizeType"/>
  </xs:simpleType>
  <xs:simpleType name="sizeType">
    <xs:restriction base="xs:integer"/>
  </xs:simpleType>

After validation against this Schema, the element is represented as:

  element sizes of type sizesType {
    1 of type sizeType,
    2 of type sizeType,
    3 of type sizeType
  }

An element with an anonymous type

  <sizes>1 2 3</sizes>

Before validation, this element is represented as:

  element sizes of type xs:untyped {
    text { "1 2 3" }
  }

Assume the following Schema.

  <xs:element name="sizes">
    <xs:simpleType>
      <xs:list itemType="xs:integer"/>
    </xs:simpleType>
  </xs:element>

After validation, this element is represented as:

  element sizes of type fs:anon1 {
    1 of type xs:integer,
    2 of type xs:integer,
    3 of type xs:integer
  }

where fs:anon1 stands for the internal anonymous name generated by the system for the sizes element.

A nillable element with xsi:type set to true

  <sizes xsi:nil="true"/>

Before validation, this element is represented as:

  element sizes of type xs:untyped {
    attribute xsi:nil of type xs:untypedAtomic { "true" of type xs:untypedAtomic }
  }

Assume the following Schema.

  <xs:element name="sizes" type="sizesType" nillable="true"/>

After validation against this Schema, the element is represented as:

  element sizes nilled of type sizesType {
    attribute xsi:nil of type xs:boolean { true of type xs:boolean }
  }

An element with a union type

  <sizes>1 two 3 four</sizes>

Before validation, this element is represented as:

  element sizes of type xs:untyped {
    text { "1 two 3 four" }
  }

Assume the following Schema:

  <xs:element name="sizes" type="sizesType"/>
  <xs:simpleType name="sizesType">
    <xs:list itemType="sizeType"/>
  </xs:simpleType>
  <xs:simpleType name="sizeType">
    <xs:union memberType="xs:integer xs:string"/>
  </xs:simpleType>

After validation against this Schema, the element is represented as:

  element sizes of type sizesType {
    1 of type xs:integer,
    "two" of type xs:string,
    3 of type xs:integer,
    "four" of type xs:string
  }

2.4 The [XPath/XQuery] Type System

The [XPath/XQuery] type system is used in the specification of the dynamic and of the static semantics of [XPath/XQuery]. This section introduces formal notations for describing types.

2.4.1 XML Schema and the [XPath/XQuery] Type System

The [XPath/XQuery] type system is based on [Schema Part 1] and [Schema Part 2]. [Schema Part 1] and [Schema Part 2] specify normatively the type information available in [XPath/XQuery]. We define the formal notation that is used in this document to describe and manipulate types in inference rules. Formal types are used for specification purposes only and are not exposed to the [XPath/XQuery] user.

Representation of content models. For the purpose of static typing, the [XPath/XQuery] type system only describes minOccurs, maxOccurs, and minLength, maxLength on list types for the occurrences that correspond to the DTD operators +, *, and ?. Choices are represented using the DTD operator |. All groups are represented using the interleaving operator (&).

Representation of anonymous types. To clarify the semantics, the [XPath/XQuery] type system makes all anonymous types explicit.

Representation of XML Schema simple type facets and identity constraints. For simplicity, XML Schema simple type facets and identity constraints are not formally represented in the [XPath/XQuery] type system. However, an [XPath/XQuery] implementation supporting XML Schema import and validation must take simple type facets and identity constraints into account.

This document describe types in the [XPath/XQuery] types system, as well as the operations and properties over those types which are used to define the [XPath/XQuery] static typing feature. The two most important properties are whether a data instances matches a type, and whether a type is a subtype of another. Those properties are described in [8.3 Judgments for type matching]. This document does not describe all other possible properties over those types.

The mapping from XML Schema into the [XPath/XQuery] type system is given in [D Importing Schemas]. The rest of this section is organized as follows. [2.4.2 Item types] describes item types, [2.4.3 Content models] describes content models, and [2.4.4 Top level definitions] describe top-level type declarations.

2.4.2 Item types

An item type is either an atomic type, an element type, an attribute type, a document node type, a text node type, a comment node type, or a processing instruction type. We distinguish between document nodes, attribute nodes, and nodes that can occur in element content (elements, comments, processing instructions, and text nodes), as we need to refer to element content types later in the formal semantics.

Item Types
[25 (Formal)]    FormalItemType    ::=    AtomicTypeName | NodeType
[28 (Formal)]    AtomicTypeName    ::=    TypeName
[26 (Formal)]    NodeType    ::=    DocumentType
| AttributeType
| ElementContentType
[27 (Formal)]    ElementContentType    ::=    ElementType
| "comment"
| "processing-instruction"
| "text"
[29 (Formal)]    ElementType    ::=    "element" ElementNameOrWildcard OptTypeSpecifier
[4 (Formal)]    ElementNameOrWildcard    ::=    QName | "*"
[5 (Formal)]    AttributeNameOrWildcard    ::=    QName | "*"
[77 (Formal)]    OptTypeSpecifier    ::=    TypeSpecifier?
[30 (Formal)]    TypeSpecifier    ::=    OptNillable TypeReference
[31 (Formal)]    AttributeType    ::=    "attribute" AttributeNameOrWildcard OptTypeReference
[75 (Formal)]    OptNillable    ::=    Nillable?
[32 (Formal)]    Nillable    ::=    "nillable"
[78 (Formal)]    OptTypeReference    ::=    TypeReference?
[36 (Formal)]    TypeReference    ::=    "of" "type" TypeName
[45 (Formal)]    DocumentType    ::=    "document" ("{" Type "}")?

An element or attribute type has a name or wildcard, and an optional type reference. A name alone corresponds to a reference to a global element or attribute declaration. A name with a type reference corresponds to a local element or attribute declaration. "element *" or "attribute *" alone refers to the wildcard types for any element or any attribute. In addition, an element type has an optional nillable flag that indicates whether the element can be nilled or not.

A document type has an optional content type. If no content type is given, then the type is treated as being the wildcard type for documents, i.e., a sequence of text and element nodes. For consistency with element nodes, PIs and comments are not indicated in that wildcard type, but may occur in instances.

Note

Generic node types (e.g., node()) such as used in the SequenceType production, are interpreted in the type system as a union of the corresponding node types (e.g., element,attribute,text,comment and processing-instruction nodes) and therefore do not appear in the grammar. The semantics of sequence types is described in [3.5.4 SequenceType Matching].

Examples

The following is a text node type

  text

The following is a type for all elements

  element * of type xs:anyType

The following is a type for all elements of type string

  element * of type xs:string

The following is a type for a nillable element of type string and with name size

  element size nillable of type xs:string

The following is a reference to a global attribute declaration

  attribute sizes

The following is a type for elements with anonymous type fs:anon1:

  element sizes of type fs:anon1

2.4.3 Content models

Following XML Schema, types in [XPath/XQuery] are composed from item types by optional, one or more, zero or more, all group, sequence, choice, empty sequence (written empty), or empty choice (written none).

The type empty matches the empty sequence. The type none matches no values. none is the identity for choice, that is (Type | none) = Type. The type none is the static type for [7.2.9 The fn:error function].

Types
[24 (Formal)]    Type    ::=    FormalItemType
| (Type OccurrenceIndicator)
| (Type "&" Type)
| (Type "," Type)
| (Type "|" Type)
| "empty"
| "none"
| ("(" Type ")")

The [XPath/XQuery] type system includes three binary operators on types: ",", "|" and "&", corresponding respectively to sequence, choice and all groups in Schema. The [XPath/XQuery] type system includes three unary operators on types: "*", "+", and "?", corresponding respectively to zero or more instances of the type, one or more instances of the type, or an optional instance of the type.

The "&" operator builds the "interleaved product" of two types. The type Type1 & Type2 matches any sequence that is an interleaving of two sequences of items, Value1 and Value2, with Value1 matching Type1 and Value2 matching Type2. The interleaving of two sequences of items Value1 and Value2 is any sequence Value0 such that there is an ordered partition of Value0 into the two sub-sequences Value1 and Value2. The interleaved product captures the semantics of all groups in XML Schema, but is more general as it applies to arbitrary types. All groups in XML Schema are restricted to apply only on global or local element declarations with minOccurs 0 or 1, and maxOccurs 1.

For example, consider the types Type1 = xs:integer,xs:integer,xs:integer and Type2 = xs:string,xs:string. Value1 = (1,2,3) matches the type Type1 and Value2 = ("a","b") matches the type Type2. Any of the following Value0 are interleavings of Value1 and Value2, and therefore match the type (Type1 & Type2):

Value0 = (1,2,3,"a","b")
Value0 = (1,2,"a",3,"b")
Value0 = (1,2,"a","b",3)
Value0 = (1,"a",2,3,"b")
Value0 = (1,"a",2,"b",3)
Value0 = (1,"a","b",2,3)
Value0 = ("a",1,2,3,"b")
Value0 = ("a",1,2,"b",3)
Value0 = ("a",1,"b",2,3)
Value0 = ("a","b",1,2,3)

Types precedence order. To improve readability when writing types, we assume the following precedence order between operators on types.

# Operator
1 | (choice)
2 & (interleaving)
3 , (sequence)
4 *, +, ? (occurrence)

Parenthesis can be used to enforce precedence. For instance

  xs:string | xs:integer, xs:float*

is equivalent to

  xs:string | (xs:integer, (xs:float*))

and a different precedence can be obtained by writing

  ((xs:string | xs:integer), xs:float)*

Examples

A sequence of elements

The "," operator builds the "sequence" of two types. For example,

  element title of type xs:string, element year of type xs:integer

is a sequence of an element title of type string followed by an element year of type integer.

The union of two element types

The "|" operator builds the "union" of two types. For example,

  element editor of type xs:string | element bib:author

means either an element editor of type string, or a reference to the global element bib:author.

An all group of two elements

The "&" operator builds the "interleaved product" of two types. For example,

  (element a & element b) =
    element a, element b
  | element b, element a

which specifies that the a and b elements can occur in any order.

An empty type

The following type matches the empty sequence.

  empty

A sequence of zero or more elements

The following type matches zero or more elements each of which can be a surgeon or a plumber.

  (element surgeon | element plumber)*

Notation

The grammar for Type describe above is general enough to capture type infered for arbitrary expression, as well as to represent the content of an in [Schema Part 1]. In a few cases, inference rules rely on the fact that a given type is a type validly describing the content of an element. To capture those cases, we introduce the following auxiliary grammar productions to describe more precisely the attribute declarations and the content model for an element.

[42 (Formal)]    AttributeModel    ::=    AttributeType
| (AttributeType "?")
| (AttributeModel "&" AttributeModel)
| ("(" ")")
[43 (Formal)]    ElementModel    ::=    ElementType
| (ElementType "?")
| (ElementModel "&" ElementModel)
| ("(" ")")
| "none"

2.4.4 Top level definitions

Top level definitions correspond to global element declarations, global attribute declarations and type definitions in XML Schema.

Type Definitions
[40 (Formal)]    Definitions    ::=    (Definition Definitions)?
[39 (Formal)]    Definition    ::=    ("define" "element" ElementName OptSubstitution OptNillable TypeReference)
| ("define" "attribute" AttributeName TypeReference)
| ("define" "type" TypeName TypeDerivation)
[76 (Formal)]    OptSubstitution    ::=    Substitution?
[41 (Formal)]    Substitution    ::=    "substitutes" "for" ElementName
[33 (Formal)]    TypeDerivation    ::=    ComplexTypeDerivation | AtomicTypeDerivation
[34 (Formal)]    ComplexTypeDerivation    ::=    Derivation? OptMixed "{" Type? "}"
[35 (Formal)]    AtomicTypeDerivation    ::=    "restricts" AtomicTypeName
[37 (Formal)]    Derivation    ::=    ("restricts" TypeName)
| ("extends" TypeName)
[74 (Formal)]    OptMixed    ::=    Mixed?
[38 (Formal)]    Mixed    ::=    "mixed"

A type definition has a name (possibly anonymous) and a type derivation. In the case of a complex type, the derivation indicates whether it is derived by extension or restriction, its base type, and its content model, with an optional flag indicating if it has mixed content.

Note the type system allows recursive types, following the rules defined in [Schema Part 1].

Example

For instance, the following complex type

 <complexType name="UKAddress">
   <complexContent>
     <extension base="ipo:Address">
       <sequence>
         <element name="postcode" type="ipo:UKPostcode"/>
       </sequence>
       <attribute name="exportCode" type="positiveInteger" fixed="1"/>
     </extension>
   </complexContent>
 </complexType>

is represented as follows

  define type UKAddress extends ipo:Address {
    attribute exportCode of type ipo:UKPostcode,
    element postcode of type positiveInteger
  };

Example

In the case of simple types derived by union or list, the derivation is always a restriction from the base type xs:anySimpleType, and has a content which is a union of the member types, or a repetition of the item type. For instance, the two following simple type declarations

<xsd:simpleType name="listOfMyIntType">
  <xsd:list itemType="myInteger"/>
</xsd:simpleType>

<xsd:simpleType name="zipUnion">
  <xsd:union memberTypes="USState FrenchRegion"/>
</xsd:simpleType>

are represented as follows

define type listOfMyIntType restricts xs:anySimpleType {
  myInteger*
}

define type zipUnion restricts xs:anySimpleType {
  USState | FrenchRegion
}

Example

In the case of an atomic type, it just indicates its base type. For instance, the following type definition

<xsd:simpleType name="SKU">
 <xsd:restriction base="xsd:string">
  <xsd:pattern value="\d{3}-[A-Z]{2}"/>
 </xsd:restriction>
</xsd:simpleType>

is represented as follow

  define type SKU restrict xsd:string;

Example

When the type derivation is omitted, the type derives by restriction from xs:anyType. For instance:

  define type Bib { element book* } =
  define type Bib restricts xs:anyType { element book* }

Example

Empty content can be indicated with the explicit empty sequence, or omitted, as in:

  define type Bib { } =
  define type Bib { empty }

Global element and attribute declarations always have a name and a reference to a (possibly anonymous) type. A global element declaration also may declare a substitution group for the element and whether the element is nillable.

Example

A type declaration with one element name of type xs:string follows by one or more elements street of type xs:string.

  define type Address {
    element name of type xs:string,
    element street of type xs:string*
  }

Example

A type declaration with complex content derived by extension

  define type USAddress extends Address {
    element zip name of type xs:integer
  }

Example

A type declaration with mixed content

  define type Section mixed {
    (element h1 of type xs:string |
     element p of type xs:string |
     element div of type Section)*
  }

Example

A type declaration with simple content derived by restriction

  define type SKU restricts xs:string

Example

An element declaration

  define element address of type Address

Example

An element declaration with a substitution group

  define element usaddress substitutes for address of type USAddress

Example

An element declaration which is nillable

  define element zip nillable of type xs:integer

2.4.5 Example of a complete Schema

Here is a schema describing purchase orders from [XML Schema Part 0].

  <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  
   <xsd:annotation>
    <xsd:documentation xml:lang="en">
     Purchase order schema for Example.com.
     Copyright 2000 Example.com. All rights reserved.
    </xsd:documentation>
   </xsd:annotation>
  
   <xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
  
   <xsd:element name="comment" type="xsd:string"/>
  
   <xsd:complexType name="PurchaseOrderType">
    <xsd:sequence>
     <xsd:element name="shipTo" type="USAddress"/>
     <xsd:element name="billTo" type="USAddress"/>
     <xsd:element ref="comment" minOccurs="0"/>
     <xsd:element name="items"  type="Items"/>
    </xsd:sequence>
    <xsd:attribute name="orderDate" type="xsd:date"/>
   </xsd:complexType>
  
   <xsd:complexType name="USAddress">
    <xsd:sequence>
     <xsd:element name="name"   type="xsd:string"/>
     <xsd:element name="street" type="xsd:string"/>
     <xsd:element name="city"   type="xsd:string"/>
     <xsd:element name="state"  type="xsd:string"/>
     <xsd:element name="zip"    type="xsd:decimal"/>
    </xsd:sequence>
    <xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
   </xsd:complexType>
  
   <xsd:complexType name="Items">
    <xsd:sequence>
     <xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
      <xsd:complexType>
        <xsd:sequence>
         <xsd:element name="productName" type="xsd:string"/>
         <xsd:element name="quantity">
          <xsd:simpleType>
           <xsd:restriction base="xsd:positiveInteger">
            <xsd:maxExclusive value="100"/>
           </xsd:restriction>
          </xsd:simpleType>
         </xsd:element>
         <xsd:element name="USPrice"  type="xsd:decimal"/>
         <xsd:element ref="comment"   minOccurs="0"/>
         <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
        </xsd:sequence>
        <xsd:attribute name="partNum" type="SKU" use="required"/>
      </xsd:complexType>
     </xsd:element>
    </xsd:sequence>
   </xsd:complexType>
  
   <!-- Stock Keeping Unit, a code for identifying products -->
   <xsd:simpleType name="SKU">
    <xsd:restriction base="xsd:string">
     <xsd:pattern value="\d{3}-[A-Z]{2}"/>
    </xsd:restriction>
   </xsd:simpleType>
  
  </xsd:schema>

Here is the mapping of the above schema into the [XPath/XQuery] type system.

  declare namespace xsd = "http://www.w3.org/2001/XMLSchema";

  define element purchaseOrder of type PurchaseOrderType;
 
  define element comment of type xsd:string;
  
  define type PurchaseOrderType {
    attribute orderDate of type xsd:date?,
    element shipTo of type USAddress,
    element billTo of type USAddress,
    element comment?,
    element items of type Items
  };

  define type USAddress {
    attribute country of type xsd:NMTOKEN,
    element name of type xsd:string,
    element street of type xsd:string,
    element city of type xsd:string,
    element state of type xsd:string,
    element zip of type xsd:decimal
  };

  define type Items {
    attribute partNum of type SKU,
    element item of type fs:anon1*
  };

  define type fs:anon1 {
    element productName of type xsd:string,
    element quantity of type fs:anon2,
    element USPrice of type xsd:decimal,
    element comment?,
    element shipDate of type xsd:date?
  };

  define type fs:anon2 restricts xsd:positiveInteger;

  define type SKU restrict xsd:string;

Note that the two anonymous types in the item element declarations are mapping to types with names fs:anon1 and fs:anon2.

The following additional definitions illustrate how more advanced XML Schema features (a complex type derived by extension, an anonymous simple type derived by restriction, and substitution groups) are represented in the [XPath/XQuery] type system.

  <complexType name="NYCAddress">
    <complexContent>
     <extension base="USAddress">
      <sequence>
       <element ref="apt"/>
      </sequence>
     </extension>
    </complexContent>
  </complexType>

  <element name="apt">
    <xsd:simpleType>
     <xsd:restriction base="xsd:positiveInteger">
      <xsd:maxExclusive value="10000"/>
     </xsd:restriction>
    </xsd:simpleType>
  </element>

  <element name="usaddress" substitutionGroup="address" type="USAddress"/>
  <element name="nycaddress" substitutionGroup="usaddress" type="NYCAddress"/>

The above definitions are mapped into the [XPath/XQuery] type system as follows:

  define type NYCAddress extends USAddress {
    element apt
  }

  define element apt of type fs:anon3

  define type fs:anon3 restricts xsd:positiveInteger

  define element usaddress  substitutes for address of type USAddress
  define element nycaddress substitutes for usaddress of type NYCAddress

2.5 Functions and operators

The [Functions and Operators] document defines built-in functions available in [XPath/XQuery]. A number of these functions are used to define the [XPath/XQuery] semantics; those functions are listed in [C.1 Functions and Operators used in the Formal Semantics].

Many functions in the [Functions and Operators] document are generic: they perform operations on arbitrary components of the data model, e.g., any kind of node, or any sequence of items. For instance, the fn:unordered returns its input sequence in an implementation-dependent order. The signature of the fn:unordered function takes arbitrary items as input and output:

  fn:unordered($sourceSeq as item()*) as item()*

As defined, this signature provides little useful type information. For such functions, better type information can often be obtained by having the output type depend on the type of input parameters. For instance, if the function fn:unordered is applied on a sequence of a elements, the result is also a sequence of a elements.

In order to provide better static typing for those functions, specific static typing rules are given in [7 Additional Semantics of Functions].

3 Basics

The organization of this section parallels the organization of Section 2 BasicsXQ.

3.1 Expression Context

Introduction

The expression context for a given expression consists of all the information that can affect the result of the expression. This information is organized into the static context and the dynamic context. This section specifies the environments that represent the context information used by [XPath/XQuery] expressions.

3.1.1 Static Context

Notation

We introduce the following auxiliary grammar production to describe function signatures.

[85 (Formal)]    FunctionSig    ::=    "declare" "function" expanded-QName "(" TypeList? ")" "as" SequenceType
[86 (Formal)]    TypeList    ::=    SequenceType ("," Type)*

statEnv denotes the environment available during static analysis. Static analysis may extend parts of the static environment. The static environment is also available during dynamic evaluation.

If analysis of an expression relies on some component of the static context that has not been assigned a value, a static error is raised.

The following environment components are part of the static environment:

statEnv.xpath1.0_compatibility
The statEnv.xpath1.0_compatibility environment component designates the XPath 1.0 compatibility flag in the [XPath/XQuery] static context. It specifies whether the semantic rules for backward compatibility with XPath 1.0 are in effect. This document defines the formal semantics for XPath 2.0 only when the XPath 1.0 backward compatibility rules are not in effect.
statEnv.namespace
The statEnv.namespace environment component designates the statically known namespaces in the [XPath/XQuery] static context.
The statEnv.namespace environment component maps a namespace prefix (NCName) onto a namespace kind and a namespace URI (AnyURI), the null namespace (#NULL-NAMESPACE), or (#UNDECLARED). The namespace kind is either passive or active. The namespace kind determines whether a namespace node is created for an element during element construction. The (#UNDECLARED) value may be used to indicate that the prefix has been undeclared, and may occur only if the implementation supports [XML Names 1.1].
statEnv.default_elem_namespace
The statEnv.default_elem_namespace environment component designates the default element/type namespace in the [XPath/XQuery] static context.
The statEnv.default_elem_namespace environment component contains a namespace URI (a AnyURI) or the null namespace (#NULL-NAMESPACE) and is used for any unprefixed QName appearing in a position where an element or type name is expected.
statEnv.default_function_namespace
The statEnv.default_function_namespace environment component designates the default function namespace in the [XPath/XQuery] static context.
The statEnv.default_function_namespace environment component contains a namespace URI (a AnyURI) or the null namespace (#NULL-NAMESPACE) and is used for any unprefixed QName appearing as the function name in a function call.
statEnv.typeDefn
The statEnv.typeDefn environment component designates the in-scope schema types in the [XPath/XQuery] static context.
The statEnv.typeDefn environment component maps expanded type names (expanded TypeNames) onto their type definition (Definition). A type name may be globally declared or anonymous.
statEnv.elemDecl
The statEnv.elemDecl environment component designates the in-scope element declarations in the [XPath/XQuery] static context.
The statEnv.elemDecl environment component maps expanded element names (expanded ElementNames) onto their declaration (Definition).
statEnv.attrDecl
The statEnv.attrDecl environment component designates the in-scope attribute declarations in the [XPath/XQuery] static context.
The statEnv.attrDecl environment component maps expanded attribute names (expanded AttributeNames) onto their declaration (Definition).
statEnv.varType
The statEnv.varType environment component designates the in-scope variables in the [XPath/XQuery] static context.
The statEnv.varType environment component maps expanded variable names (expanded VarName) to their static type (Type).
The context item static type in the [XPath/XQuery] static context is represented by the binding of the variable $fs:dot to its corresponding type in statEnv.varType.
statEnv.funcType
The statEnv.funcType environment component designates the function signatures in the [XPath/XQuery] static context.
The statEnv.funcType environment component stores the static type signatures of functions. Because [XPath/XQuery] allows multiple functions with the same name differing in the number of parameters, this environment component maps an expanded QName and an arity to a function signatures FunctionSig.
statEnv.collations
The statEnv.collations environment component designates the statically known collations in the [XPath/XQuery] static context.
The statEnv.collations environment component maps a unique namespace URI (a AnyURI) to a pair of functions: the first function takes a set of strings and returns a sequence containing those strings in sorted order; and the second function takes two strings, returns true if they are considered equal, and false if not.
statEnv.defaultCollation
The statEnv.defaultCollation environment component designates the default collation in the [XPath/XQuery] static context.
The statEnv.defaultCollation environment component is a pair of functions as described in statEnv.collations above.
statEnv.constructionMode
The statEnv.constructionMode environment component designates the construction mode in the [XPath/XQuery] static context.
The statEnv.constructionMode environment component is one of preserve or strip.
statEnv.orderingMode
The statEnv.orderingMode environment component designates the ordering mode in the [XPath/XQuery] static context.
The statEnv.orderingMode environment component is one of ordered or unordered.
statEnv.defaultEmptySequenceOrder
The statEnv.defaultEmptySequenceOrder environment component designates the default order for empty sequences in the [XPath/XQuery] static context.
The statEnv.defaultEmptySequenceOrder environment component controls whether an empty sequence is interpreted as the greatest value or as the least value during processing of an order by clause in a FLWOR expression. Its value may be greatest or least.
statEnv.boundarySpace
The statEnv.boundarySpace environment component designates the boundary-space policy in the [XPath/XQuery] static context.
The statEnv.boundarySpace environment component controls the processing of boundary whitespace by element constructors. Its value may be preserve or strip.
statEnv.copyNamespacesMode
The statEnv.copyNamespacesMode environment component designates the copy-namespaces mode in the [XPath/XQuery] static context.
The statEnv.copyNamespacesMode environment component controls the namespace bindings that are assigned when an existing element node is copied by an element constructor. Its value consists of two parts: preserve or no-preserve, and inherit or no-inherit.
statEnv.baseURI
The statEnv.baseURI environment component designates the base URI in the [XPath/XQuery] static context.
The statEnv.baseURI environment component contains a unique namespace URI (a AnyURI).
statEnv.docType
The statEnv.docType environment component designates the statically known documents in the [XPath/XQuery] static context. It contains the static type for the input documents, and is used to provide the static type to the fn:doc function.
The statEnv.docType environment component contains bindings from input URIs (a AnyURI) to types (a Type).
statEnv.collectionType
The statEnv.collectionType environment component designates the statically known collections in the [XPath/XQuery] static context. It contains the static type for the input collections, and is used to provide the static type to the fn:collection function.
The statEnv.collectionType environment component contains bindings from input URIs (a AnyURI) to types (a Type).
statEnv.defaultCollectionType
The statEnv.defaultCollectionType environment component designates the statically known default collection type in the [XPath/XQuery] static context. It contains the static type for the default collection, and is used to provide the static type to the fn:collection function when called with no arguments.
The statEnv.defaultCollectionType environment component contains type (a Type).

Note that the boundary-space behavior is not formally specified in this document.

An initial environment is set up when [expression/query] processing begins, containing, for example, the function signatures of all built-in functions. The initial values for the static context are defined in Section C Context ComponentsXQ and Section C Context ComponentsXP and is denoted by statEnvDefault in the Formal Semantics.

Here is an example that shows how the static environment is modified in response to a namespace definition.

dynEnv |-  URILiteral has atomic value AnyURI
statEnv + namespace(NCName => (passive, AnyURI))  |-  Expr : Type

statEnv |-  declare namespace NCName = URILiteral; Expr : Type

This rule reads as follows: "the phrase on the bottom (a namespace declaration in the query prolog followed by a sequence of expressions) is well-typed (accepted by the static typing rules) within an environment statEnv if the expression above the line is well-typed in the environment obtained from statEnv by adding the namespace declaration".

The helper function fs:active_ns(statEnv) returns all the active in-scope namespaces in the given static environment.

For each attribute and element node in Value, such that the node has name expanded-QName in the namespace AnyURI, the helper function fs:get_static_ns_from_items(statEnv, Value) returns the in-scope namespace that corresponds to AnyURI. This is a reverse-lookup on statEnv.namespace by AnyURI.

3.1.1.1 Resolving QNames to Expanded QNames

A common use of the static environment is to expand a QName by looking up the URI that corresponds to the QName's namespace prefix in the statEnv.namespace environment component and by constructing an expanded-QNameDM, which contains the URI and the QName's local part. Element and type names may be in the null namespace, that is, there is no URI associated with their namespace prefix. The null namespace is denoted by the special value #NULL-NAMESPACE.

The auxiliary judgments below expand an element, type, attribute, variable, or function QName by looking up the namespace prefix in statEnv.namespace or, if the QName is unqualified, by using the appropriate default namespace.

Notation

The judgment

holds when the element or type QName expands to the given expanded QName.

The judgment

holds when the attribute QName expands to the given expanded QName.

We use Variable to denote the expanded QNames of variables.

The judgment

statEnv |-  QName of var expands to Variable

holds when the variable QName expands to the given expanded QName.

The judgment

holds when the function QName expands to the given expanded QName.

Semantics

Note that none of the inference rules can infer a resolved name in the case a given namespace prefix is bound to the (#UNDECLARED) value. As a result, namespace resolution will fail if the implementation supports [XML Names 1.1] and a given namespace prefix has been undeclared.

An element or type QName consisting of a prefix NCName and a local part NCName expands to the URI (or the null namespace) corresponding to that prefix and the local part.

statEnv.namespace(NCName1) = (NamespaceKind,AnyURI-or-#NULL-NAMESPACE)

statEnv |-  NCName1:NCName2 of elem/type expands to (AnyURI-or-#NULL-NAMESPACE, NCName2)

An element or type QName consisting only of a local part NCName expands to the default element/type namespace and the local part.

statEnv.default_elem_namespace = AnyURI-or-#NULL-NAMESPACE

statEnv |-  NCName of elem/type expands to (AnyURI-or-#NULL-NAMESPACE, NCName)

An attribute QName consisting of a prefix NCName and a local part NCName expands to the URI (or the null namespace) corresponding to the prefix and the local part.

statEnv.namespace(NCName1) = (NamespaceKind,AnyURI-or-#NULL-NAMESPACE)

statEnv |-  NCName1:NCName2 of attr expands to (AnyURI-or-#NULL-NAMESPACE, NCName2)

An attribute QName consisting only of a local part NCName expands to the null namespace and the local part.


statEnv |-  NCName of attr expands to (#NULL-NAMESPACE, NCName)

A variable QName consisting of a prefix NCName and a local part NCName expands to the URI that corresponds to the prefix and the local part.

statEnv.namespace(NCName1) = (NamespaceKind,AnyURI)

statEnv |-  NCName1:NCName2 of var expands to (AnyURI, NCName2)

A variable QName consisting only of a local part NCName expands to the null namespace and the local part.


statEnv |-  NCName of var expands to (#NULL-NAMESPACE, NCName)

A function QName consisting of a prefix NCName and a local part NCName expands to the URI that corresponds to the prefix and the local part.

statEnv.namespace(NCName1) = (NamespaceKind,AnyURI)

statEnv |-  NCName1:NCName2 of func expands to (AnyURI, NCName2)

A function QName consisting only of a local part NCName expands to the default function namespace URI and the local part.

statEnv.default_function_namespace = AnyURI

statEnv |-  NCName of func expands to (AnyURI, NCName)

3.1.2 Dynamic Context

dynEnv denotes the environment available during dynamic evaluation. Dynamic evaluation may extend parts of the dynamic environment.

If evaluation of an expression relies on some component of the dynamic context that has not been assigned a value, a dynamic error is raised.

The following environment components are part of the dynamic environment:

dynEnv.varValue
The dynEnv.varValue environment component corresponds to the variable values, the context item, the context position and the context size in the [XPath/XQuery] evaluation context.
The dynamic value environment component maps an expanded variable name (expanded VarName) to the variable's value (Value) or to the value #IMPORTED(AnyURI), if the variable is defined in the imported module with namespace AnyURI.
dynEnv.funcDefn
The dynEnv.funcDefn environment component corresponds to the function implementations (or definition) part of the [XPath/XQuery] dynamic context.
The dynEnv.funcDefn environment component maps an expanded function name and parameter signature of the form "expanded-QName (Type1, ..., Typen)" to the remainder of the corresponding function definition. If the function is defined in [Functions and Operators], the function definition is the value #BUILT-IN. If the function is externally defined, the function definition is the value #EXTERNAL. If the function is defined in the imported module with namespace AnyURI, the function definition is the value #IMPORTED(AnyURI). If the function is locally declared, the function definition is of the form "(Expr, Variable1,..., Variablen)", where Expr is the function body and Variable1, ..., Variablen are the function parameters.
The initial function environment component (dynEnvDefault.funcDefn) maps the signatures of the internal functions defined in [C.2 Mapping of Overloaded Internal Functions] and the signatures of the functions defined in [Functions and Operators] to #BUILT-IN.
dynEnv.dateTime
The dynEnv.dateTime environment component corresponds to the current dateTime in the [XPath/XQuery] dynamic context.
dynEnv.timezone
The dynEnv.timezone environment component corresponds to the implicit timezone in the [XPath/XQuery] dynamic context and is used by the timezone related functions in [Functions and Operators].
dynEnv.docValue
The dynEnv.docValue environment component corresponds to the available documents in the [XPath/XQuery] dynamic context. It contains the document nodes corresponding to input documents, and is used to provide the dynamic value of the fn:doc function.
The dynEnv.docValue environment component contains bindings from input URIs (a AnyURI) to documents (a DocumentValue).
dynEnv.collectionValue
The dynEnv.collectionValue environment component corresponds to the available collections in the [XPath/XQuery] dynamic context. It contains the root nodes corresponding to the input collections, and is used to provide the dynamic value of the fn:collection function.
The dynEnv.collectionValue environment component contains bindings from input URIs (a AnyURI) to a sequence of nodes.
dynEnv.defaultCollectionValue
The dynEnv.defaultCollectionValue environment component corresponds to the default collection in the [XPath/XQuery] dynamic context. It contains the sequence of nodes corresponding to the default collection, and is used to provide the dynamic value of the fn:collection function when called with no arguments.
The dynEnv.defaultCollectionValue environment component contains a sequence of nodes.

The initial values for the dynamic context are defined in Section C Context ComponentsXQ and Section C Context ComponentsXP. The corresponding initial dynamic environment is denoted by dynEnvDefault in the Formal Semantics.

The following Formal Semantics variables represent the context item, context position, and context size properties of the dynamic context:

Built-in Variable   Represents:
$fs:dot context item
$fs:position context position
$fs:last context size

Within this document, variables with the "fs" prefix are reserved for use in the formal specification. Values of $fs:position and $fs:last can be obtained by invoking the fn:position and fn:last functions, respectively. Note that the type for those variables is obtained as for any other variables. As expected the type of $fs:position and $fs:last is always xs:integer while the type of $fs:dot depends on the context in which it is being used.

3.2 Processing Model

This section reviews the processing model for [XPath/XQuery]. The [XPath/XQuery] processing model is defined normatively in Section 2.2 Processing ModelXQ. This section also explains how the main notations (normalization rules, static typing rules, and dynamic evaluation rules) relate to the phases in that processing model.

3.2.1 Processing model

The following figure depicts the [XPath/XQuery] processing model

Processing Model Overview

Figure 1: Processing Model Overview

This processing model is not intended to describe an actual implementation, although a naive implementation might be based upon it. It does not prescribe an implementation technique, but any implementation should produce the same results as obtained by following this processing model and applying the rest of the Formal Semantics specification.

Query processing consists of two phases: a static analysis phase and a dynamic evaluation phase. Static analysis is further divided into four sub-phases. Typically, each phase consumes the result of the previous phase and generates output for the next phase. When processing query prologs, these phases may be mutually dependent (See [5 Modules and Prologs]). For each processing phase, we point to the relevant notations introduced later in the document.

[Definition: The static analysis phase depends on the expression itself and on the static context. The static analysis phase does not depend on input data (other than schemas).]

The purpose of the static analysis phase is to detect errors, e.g., syntax errors or type errors, at compile time rather than at run-time. If no error occurs, the result of static analysis could be some compiled form of [expression/query], suitable for execution by a compiled-[expression/query] processor. Static analysis consists of the following sub-phases:

  1. Parsing. (Step SQ1 in Figure 1). The grammar for the [XPath/XQuery] syntax is defined in [XQuery 1.0: An XML Query Language]. Parsing may generate syntax errors. If no error occurs, an internal operation tree of the parsed query is created.

  2. Static Context Processing. (Steps SQ2, SQ3, and SQ4 in Figure 1). The static semantics of [expression/query] depends on the input static context. The input static context needs to be generated before the [expression/query] can be analysed. In XQuery, the input static context may be defined by the processing environment and by declarations in the Query Prolog (See [5 Modules and Prologs]). In XPath, the input static context is defined by the processing environment. The static context is denoted by statEnv.

  3. Normalization. (Step SQ5 in Figure 1). To simplify the semantics specification, some normalization is performed on the [expression/query]. The [XPath/XQuery] language provides many powerful features that make [expression/query]s simpler to write and use, but are also redundant. For instance, a complex for expression might be rewritten as a composition of several simple for expressions. The language composed of these simpler [expression/query] is called the [XPath/XQuery] Core language and is described by a grammar which is a subset of the XQuery grammar. The grammar of the [XPath/XQuery] Core language is given in [A Normalized core and formal grammars].

    During the normalization phase, each [XPath/XQuery] [expression/query] is mapped into its equivalent [expression/query] in the Core. (Note that this has nothing to do with Unicode Normalization, which works on character strings.) Normalization works by recursive application of the normalization rules over a given expression.

    Specifically the normalization phase is defined in terms of the static part of the context (statEnv) and a [expression/query] (Expr) abstract syntax tree. Formal notations for the normalization phase are introduced in [3.2.2 Normalization mapping rules].

    After normalization, the full semantics is obtained by giving a semantics to the normalized Core [expression/query]. This is done during the last two phases.

  4. Static type analysis. (Step SQ6 in Figure 1). Static type analysis is optional. If this phase is not supported, then normalization is followed directly by dynamic evaluation.

    Static type analysis checks whether each [expression/query] is well-typed, and if so, determines its static type. Static type analysis is defined only for Core [expression/query]. Static type analysis works by recursive application of the static typing rules over a given expression.

    If the [expression/query] is not well-typed, static type analysis yields a type error. For instance, a comparison between an integer value and a string value might be detected as an type error during the static type analysis. If static type analysis succeeds, it yields an abstract syntax tree where each sub-expression is associated with its static type.

    More precisely, the static analysis phase is defined in terms of the static context (statEnv) and a Core [expression/query] (CoreExpr). Formal notations for the static analysis phase are introduced in [3.2.3 Static typing judgment].

    Static typing does not imply that the content of XML documents must be rigidly fixed or even known in advance. The [XPath/XQuery] type system accommodates "flexible" types, such as elements that can contain any content. Schema-less documents are handled in [XPath/XQuery] by associating a standard type with the document, such that it may include any legal XML content.

If the static analysis phase succeeds, the dynamic evaluation phase (sometimes also called "execution") evaluates a query on input document(s).

  1. Dynamic Context Processing. (Steps DQ2 and DQ3 in Figure 1).The dynamic semantics of [expression/query] depends on the dynamic input context. The dynamic input context needs to be generated before the [expression/query] can be evaluated. The dynamic input context may be defined by the processing environment and by statements in the Query Prolog (See [5 Modules and Prologs]). In XPath, the dynamic input context is defined by the processing environment. The static input context is denoted by dynEnv.

  2. Dynamic Evaluation. (Steps DQ4 and DQ5 in Figure 1). This phase computes the value of an [expression/query]. The semantics of evaluation is defined only for Core [expression/query] terms. The formal description of evaluation works by recursive application of the dynamic evaluation rules over a given expression. Evaluation may result in a value OR a dynamic error, which may be a non-type error or a type error. If static typing of an expression does not raise a type error, then dynamic evaluation of the same expression will not raise a type error (and thus dynamic type checking can be avoided when static typing is enabled). Dynamic evaluation may still raise a non-type error.

    The dynamic evaluation phase is defined in terms of the static context (statEnv) and evaluation context (dynEnv), and a Core [expression/query] (CoreExpr). Formal notations for the dynamic evaluation phase are introduced in [3.2.4 Dynamic evaluation judgment].

Static type analysis catches only certain classes of errors. For instance, it can detect a comparison operation applied between incompatible types (e.g., xs:int and xs:date). Some other classes of errors cannot be detected by the static analysis and are only detected at evaluation time. For instance, whether an arithmetic expression on 32 bit integers (xs:int) yields an out-of-bound value can only be detected at run-time by looking at the data.

While implementations are free to implement different processing models, the [XPath/XQuery] static semantics relies on the existence of a static type analysis phase that precedes any access to the input data.

The above processing phases are all internal to the [XPath/XQuery] processor. They do not deal with how the [XPath/XQuery] processor interacts with the outside world, notably how it accesses actual documents and types. A typical [expression/query] engine would support at least three other important processing phases:

  1. Schema Import Processing. The [XPath/XQuery] type system is based on XML Schema. In order to perform dynamic or static typing, the [XPath/XQuery] processor needs to build type descriptions that correspond to the schema(s) of the input documents. This phase is achieved by mapping all schemas required by the [expression/query] into the [XPath/XQuery] type system. The XML Schema import phase is described in [D Importing Schemas].

  2. Data Model Generation. Expressions are evaluated on values in the [Data Model]. XML documents must be loaded into the [Data Model] before the evaluation phase. This is described in the [Data Model] and is not discussed further here.

  3. Serialization. Once the [expression/query] is evaluated, processors might want to serialize the result of the [expression/query] as actual XML documents. Serialization of data model instances is described in [Data Model Serialization] and is not discussed further here.

The parsing phase is not specified formally; the formal semantics does not define a formal model for the syntax trees, but uses the [XPath/XQuery] concrete syntax directly. More details about parsing for XQuery 1.0 can be found in the [XQuery 1.0: An XML Query Language] document and more details about parsing for XPath 2.0 can be found in the [XML Path Language (XPath) 2.0] document. No further discussion of parsing is included here.

3.2.2 Normalization mapping rules

Normalization is specified using mapping rules, which describe how a [XPath/XQuery] expression is rewritten into an expression in the [XPath/XQuery] Core. Mapping rules are also used in [D Importing Schemas] to specify how XML Schemas are imported into the [XPath/XQuery] type system.

Notation

Mapping rules are written using a square bracket notation, as follows:

 
[Object]Subscript, premises
==
Mapped Object

The original "object", and an optional list of premises, is written above the = sign. The rewritten "object" is written beneath the = sign. The subscript is used to indicate what kind of "object" is mapped, and sometimes to pass some information between mapping rules. For instance, the mapping rule [Expr]FunctionArgument(Type) is used in the normalization of [4.1.5 Function Calls] and passes a sequence type as a parameter during normalization.

Since normalization is always applied in the presence of a static context, the above rule is a shorthand for:

statEnv |- premises

statEnv |-  [Object] Subscript = Mapped Object

Most normalization rules have no premises, so they are omitted. The static environment is used in certain normalization rules (e.g. for normalization of function calls). To keep the notation simpler, the static environment is not written in the normalization rules, but it is assumed to be available.

The normalization rule that is used to map "top-level" expressions in the [XPath/XQuery] syntax into expressions in the [XPath/XQuery] Core is:

 
[Expr]Expr
==
CoreExpr

which indicates that the expression Expr is normalized to the expression CoreExpr in the [XPath/XQuery] Core (with the implied statEnv). Note that Expr within the square brackets are the expression being normalized, while the Expr in the subscript indicate that this is the main normalization rule that applies to expressions. For instance, here is the normalization rule applied to the literal integer 1.

 
[1]Expr
==
1

To simplify the specification in some cases, some further normalization may be used on the right-hand side of a normalization rule. For instance, the following normalization rules for the / operator applies normalization to the expanded expression on the right-hand side.

 
[/]Expr
==
[(fn:root(self::node()) treat as document-node())]Expr

Example

For instance, the following [expression/query]

    for $i in (1, 2),
        $j in (3, 4)
    return
      element pair { ($i,$j) }

is normalized to the Core expression

    for $i in (1, 2) return
      for $j in (3, 4) return
          element pair { ($i,$j) }

in which the "FWLR" expression is mapped into a composition of two simpler "for" expressions.

3.2.3 Static typing judgment

The static semantics is specified using static typing rules, which relate [XPath/XQuery] expressions to types and specify under what conditions an expression is well typed.

Notation

The judgment

statEnv |-  Expr : Type

holds when, in the static environment statEnv, the expression Expr has type Type.

Example

The result of static type inference is to associate a static type with every [expression/query], such that any evaluation of that [expression/query] is guaranteed to yield a value that belongs to that type.

For instance, the following expression.

   let $v := 3 return $v+5

has type xs:integer. This can be inferred as follows: the literal '3' has type integer, so the variable $v also has type integer. Since the sum of two integers is an integer, the complete expression has type integer.

Note

The type of an expression is computed by inference. Static typing rules define for each kind of expression how to compute the type of the expression given the types of its sub-expressions. Here is a simple example:

statEnv |-  Expr1 : xs:boolean      statEnv |-  Expr2 : Type2      statEnv |-  Expr3 : Type3

statEnv |-  if (Expr1) then Expr2 else Expr3 : ( Type2 | Type3 )

This rule states that if the conditional expression of an "if" expression has type boolean, then the type of the entire expression is one of the two types of its "then" and "else" clauses. Note that the resulting type is represented as a union: '(Type2|Type3)'.

The part after the |- and before : in the judgment below the line corresponds to some [expression/query], for which a type is computed. If the [expression/query] has been parsed into an internal abstract syntax tree, this usually corresponds to some node in that tree. The judgment usually has patterns in it (here Expr1, Expr2, and Expr3) that need to be matched against the children of the node in the abstract syntax tree. The judgments above the line indicate things that need to be computed to use this rule; in this case, the types of the condition expression and the two branches of the if-then-else expression. Once those types are computed (by further applying static typing rules recursively to those sub-expressions), then the type of the expression below the line can be computed. This example illustrates a general feature of the [XPath/XQuery] type system: the type of an expression depends only on the type of its sub-expressions. Static type inference is recursive, following the abstract syntax of the [expression/query]. At each point in the recursion, an inference rule whose conclusion has a structure that matches that of the premise in question is sought. If all the premises of a rule cannot be satisfied, then the static type inference has failed for the given expression, and the [expression/query] is not well-typed.

3.2.4 Dynamic evaluation judgment

The dynamic, or operational, semantics is specified using dynamic evaluation rules, which relate [XPath/XQuery] expressions to values, and in some cases specify the order in which an [XPath/XQuery] expression is evaluated.

Notation

The judgment

statEnv; dynEnv |-  Expr => Value

holds when, in the static environment statEnv and dynamic environment dynEnv, the expression Expr yields the value Value.

The static environment is used in certain cases (e.g. for type matching) during evaluation. To keep the notation simpler, the static environment is not written in the dynamic evaluation rules, but it is assumed to be available.

The inference rules used for dynamic evaluation, like those for static typing, follow a recursive structure, computing the value of expressions from the values of their sub-expressions.

3.3 Error Handling

Expressions can raise errors during static analysis or dynamic evaluation. The [Functions and Operators] [XQuery 1.0: An XML Query Language], and [XML Path Language (XPath) 2.0] specify the conditions under which an expression or operator raises an error. The user may raise an error explicitly by calling the fn:error function, which takes an optional item as an argument.

This document does not describe formally the conditions under which dynamic errors are raised. Notably, it does not specify the error codes or the rules about errors and optimization, as described in [XQuery 1.0: An XML Query Language]. Instead, this document describe the rules necessary to statically detect the subset of the [XPath/XQuery] dynamic errors known as type errorXQ.

3.4 Concepts

[XPath/XQuery] is most generally used to process documents. The representation of a document is normatively defined in [Data Model]. The functions used to access documents and collections are normatively defined in [Functions and Operators].

3.4.1 Document Order

Document order is defined in [Data Model].

3.4.2 Atomization

Atomization converts an item sequence into a sequence of atomic values and is implemented by the fn:data function. Atomization is applied to a value when the value is used in a context in which a sequence of atomic values is required.

3.4.3 Effective Boolean Value

If a sequence of items is encountered where a boolean value is expected, the item sequence's effective boolean value is used. The fn:boolean function returns the effective boolean value of an item sequence.

3.4.4 Input Sources

[XPath/XQuery] has several functions that provide access to input data, described in Section 2.4.4 Input SourcesXQ. These functions are of particular importance because they provide a way in which an expression can reference a document or a collection of documents. The dynamic semantics of these input functions are described in more detail in [Functions and Operators].

3.4.5 URI Literals

In certain places in the XQuery grammar, a statically known valid absolute URI is required. These places are denoted by the grammatical symbol URILiteral, and are treated as described in [XQuery 1.0: An XML Query Language].

3.5 Types

3.5.1 Predefined Schema Types

All the built-in types of XML Schema are recognized by [XPath/XQuery]. In addition, [XPath/XQuery] recognizes the predefined types xs:anyAtomicType, xs:untypedAtomic and xs:untyped and the duration subtypes xs:yearMonthDuration and xs:dayTimeDuration . The definition of those types in the [XPath/XQuery] type system is given below.

[Definition: The following type definition of xs:anyType reflects the semantics of the Ur type from Schema in the [XPath/XQuery] type system.]

  define type xs:anyType restricts xs:anyType {
    ( attribute * of type xs:anySimpleType )*,
    ( xs:anyAtomicType* | ( element * of type xs:anyType | text | comment | processing-instruction )* )
  }

[Definition: The following type definition of xs:anySimpleType reflects the semantics of the Ur simple type from Schema in the [XPath/XQuery] type system.]

  define type xs:anySimpleType restricts xs:anyType {
    xs:anyAtomicType*
  }

The name of the Ur simple type is xs:anySimpleType. It is derived by restriction from xs:anyType, its content is a sequence any atomic types.

[Definition: The following type definition of xs:anyAtomicType reflects the semantics of xs:anyAtomicType in the [XPath/XQuery] type system.]

  define type xs:anyAtomicType restricts xs:anySimpleType {
    ( xs:string
    | xs:boolean
    | xs:decimal
    | xs:float
    | xs:double
    | xs:duration
    | xs:dateTime
    | xs:time
    | xs:date
    | xs:gYearMonth
    | xs:gYear
    | xs:gMonthDay
    | xs:gDay
    | xs:gMonth
    | xs:hexBinary
    | xs:base64Binary
    | xs:anyURI
    | xs:QName
    | xs:NOTATION
    | xs:untypedAtomic )
  }

[Definition: The following type definitions of the XML Schema primitive types reflect the semantics of the primitive types from Schema in the [XPath/XQuery] type system.]

  define type xs:string       restricts xs:anyAtomicType
  define type xs:boolean      restricts xs:anyAtomicType
  define type xs:decimal      restricts xs:anyAtomicType
  define type xs:float        restricts xs:anyAtomicType
  define type xs:double       restricts xs:anyAtomicType
  define type xs:duration     restricts xs:anyAtomicType
  define type xs:dateTime     restricts xs:anyAtomicType
  define type xs:time         restricts xs:anyAtomicType
  define type xs:date         restricts xs:anyAtomicType
  define type xs:gYearMonth   restricts xs:anyAtomicType
  define type xs:gYear        restricts xs:anyAtomicType
  define type xs:gMonthDay    restricts xs:anyAtomicType
  define type xs:gDay         restricts xs:anyAtomicType
  define type xs:gMonth       restricts xs:anyAtomicType
  define type xs:hexBinary    restricts xs:anyAtomicType
  define type xs:base64Binary restricts xs:anyAtomicType
  define type xs:anyURI       restricts xs:anyAtomicType
  define type xs:QName        restricts xs:anyAtomicType
  define type xs:NOTATION     restricts xs:anyAtomicType

All of those primitive types derive from xs:anyAtomicType. Note that the value space of each atomic type (such as xs:string) does not appear. The value space for each type is built-in and is as defined in [Schema Part 2].

[Definition: The type xs:untypedAtomic is defined as follows.]

  define type xs:untypedAtomic restricts xs:anyAtomicType

Note that this rule does not indicate the value space of xs:untypedAtomic. By definition, xs:untypedAtomic has the same value space as xs:string.

The following example shows two atomic values. The first one is a value of type string containing "Database". The second one is an untyped atomic value containing "Database".

  "Databases" of type xs:string
  "Databases" of type xs:untypedAtomic

[Definition: The type xs:untyped is defined as follows.]

  define type xs:untyped restricts xs:anyType {
    attribute * of type xs:untypedAtomic*,
    ( element * of type xs:untyped | text | comment | processing-instruction )*
  }

[Definition: The following type definitions of the XML Schema derived types reflect the semantics of the XML Schema types derived by restriction from another atomic type.]

  define type xs:normalizedString   restricts xs:string
  define type xs:token              restricts xs:normalizedString
  define type xs:language           restricts xs:token
  define type xs:NMTOKEN            restricts xs:token
  define type xs:Name               restricts xs:token
  define type xs:NCName             restricts xs:Name
  define type xs:ID                 restricts xs:NCName
  define type xs:IDREF              restricts xs:NCName
  define type xs:ENTITY             restricts xs:NCName
  define type xs:integer            restricts xs:decimal
  define type xs:nonPositiveInteger restricts xs:integer
  define type xs:negativeInteger    restricts xs:nonPositiveInteger
  define type xs:long               restricts xs:integer
  define type xs:int                restricts xs:long
  define type xs:short              restricts xs:int
  define type xs:byte               restricts xs:short
  define type xs:nonNegativeInteger restricts xs:integer
  define type xs:unsignedLong       restricts xs:nonNegativeInteger
  define type xs:unsignedInt        restricts xs:unsignedLong
  define type xs:unsignedShort      restricts xs:unsignedInt
  define type xs:unsignedByte       restricts xs:unsignedShort
  define type xs:positiveInteger    restricts xs:nonNegativeInteger

Three XML Schema built-in derived types are derived by list, as follows. Note that those derive directly from xs:anySimpleType, since they are derived by list, and that their value space is defined using a "one or more" occurrence indicator.

  define type xs:NMTOKENS restricts xs:anySimpleType { xs:NMTOKEN+ }
  define type xs:IDREFS   restricts xs:anySimpleType { xs:IDREF+ }
  define type xs:ENTITIES restricts xs:anySimpleType { xs:ENTITY+ }

For example, here is an element whose content is of type xs:IDREFS.

  element a of type xs:IDREFS {
    "id1" of type xs:IDREF,
    "id2" of type xs:IDREF,
    "id3" of type xs:IDREF
  }

Note that the type name xs:IDREFS derives from xs:anySimpleType, but not from xs:IDREF. As a consequence, calling the following three XQuery functions with the element a as a parameter succeeds for f1 and f2, but raises a type error for f3.

  declare function f1($x as element(*,xs:anySimpleType)) { $x }
  declare function f2($x as element(*,xs:IDREFS)) { $x }
  declare function f3($x as element(*,xs:IDREF)) { $x }

[Definition: The totally ordered duration types, xs:yearMonthDuration and xs:dayTimeDuration , are derived by restriction from xs:duration.]

  define type xs:yearMonthDuration restricts xs:duration
  define type xs:dayTimeDuration   restricts xs:duration

[Definition: In addition, the Formal Semantics uses the additional type fs:numeric. This type is necessary for the specification of some of XPath type conversion rules. It is defined as follows.]

  define type fs:numeric restricts xs:anyAtomicType { xs:decimal | xs:float | xs:double }

3.5.2 Typed Value and String Value

The typed value of a node is computed by the fn:data function, and the string value of a node is computed by the fn:string function, defined in [Functions and Operators]. The normative definitions of typed value and string value are defined in [Data Model].

3.5.3 SequenceType Syntax

Introduction

Sequence types can be used in [XPath/XQuery] to refer to an XML Schema type. Sequence types are used to declare the types of function parameters and in several [XPath/XQuery] expressions.

The syntax of sequence types is described by the following grammar productions.

SequenceType
[119 (XQuery)]    SequenceTypeXQ    ::=    ("empty-sequence" "(" ")")
| (ItemType OccurrenceIndicator?)
[121 (XQuery)]    ItemTypeXQ    ::=    KindTest | ("item" "(" ")") | AtomicType
[120 (XQuery)]    OccurrenceIndicatorXQ    ::=    "?" | "*" | "+"
[122 (XQuery)]    AtomicTypeXQ    ::=    QName
[123 (XQuery)]    KindTestXQ    ::=    DocumentTest
| ElementTest
| AttributeTest
| SchemaElementTest
| SchemaAttributeTest
| PITest
| CommentTest
| TextTest
| AnyKindTest
[125 (XQuery)]    DocumentTestXQ    ::=    "document-node" "(" (ElementTest | SchemaElementTest)? ")"
[133 (XQuery)]    ElementTestXQ    ::=    "element" "(" (ElementNameOrWildcard ("," TypeName "?"?)?)? ")"
[135 (XQuery)]    SchemaElementTestXQ    ::=    "schema-element" "(" ElementDeclaration ")"
[136 (XQuery)]    ElementDeclarationXQ    ::=    ElementName
[129 (XQuery)]    AttributeTestXQ    ::=    "attribute" "(" (AttribNameOrWildcard ("," TypeName)?)? ")"
[131 (XQuery)]    SchemaAttributeTestXQ    ::=    "schema-attribute" "(" AttributeDeclaration ")"
[132 (XQuery)]    AttributeDeclarationXQ    ::=    AttributeName
[134 (XQuery)]    ElementNameOrWildcardXQ    ::=    ElementName | "*"
[138 (XQuery)]    ElementNameXQ    ::=    QName
[130 (XQuery)]    AttribNameOrWildcardXQ    ::=    AttributeName | "*"
[137 (XQuery)]    AttributeNameXQ    ::=    QName
[139 (XQuery)]    TypeNameXQ    ::=    QName
[128 (XQuery)]    PITestXQ    ::=    "processing-instruction" "(" (NCName | StringLiteral)? ")"
[127 (XQuery)]    CommentTestXQ    ::=    "comment" "(" ")"
[126 (XQuery)]    TextTestXQ    ::=    "text" "(" ")"
[124 (XQuery)]    AnyKindTestXQ    ::=    "node" "(" ")"

Core Grammar

The Core grammar productions for sequence types are:

[76 (Core)]    SequenceType    ::=    ("empty-sequence" "(" ")")
| (ItemType OccurrenceIndicator?)
[78 (Core)]    ItemType    ::=    KindTest | ("item" "(" ")") | AtomicType
[77 (Core)]    OccurrenceIndicator    ::=    "?" | "*" | "+"
[79 (Core)]    AtomicType    ::=    QName
[80 (Core)]    KindTest    ::=    DocumentTest
| ElementTest
| AttributeTest
| SchemaElementTest
| SchemaAttributeTest
| PITest
| CommentTest
| TextTest
| AnyKindTest
[82 (Core)]    DocumentTest    ::=    "document-node" "(" (ElementTest | SchemaElementTest)? ")"
[90 (Core)]    ElementTest    ::=    "element" "(" (ElementNameOrWildcard ("," TypeName "?"?)?)? ")"
[92 (Core)]    SchemaElementTest    ::=    "schema-element" "(" ElementDeclaration ")"
[93 (Core)]    ElementDeclaration    ::=    ElementName
[86 (Core)]    AttributeTest    ::=    "attribute" "(" (AttribNameOrWildcard ("," TypeName)?)? ")"
[88 (Core)]    SchemaAttributeTest    ::=    "schema-attribute" "(" AttributeDeclaration ")"
[89 (Core)]    AttributeDeclaration    ::=    AttributeName
[91 (Core)]    ElementNameOrWildcard    ::=    ElementName | "*"
[95 (Core)]    ElementName    ::=    QName
[87 (Core)]    AttribNameOrWildcard    ::=    AttributeName | "*"
[94 (Core)]    AttributeName    ::=    QName
[96 (Core)]    TypeName    ::=    QName
[85 (Core)]    PITest    ::=    "processing-instruction" "(" (NCName | StringLiteral)? ")"
[84 (Core)]    CommentTest    ::=    "comment" "(" ")"
[83 (Core)]    TextTest    ::=    "text" "(" ")"
[81 (Core)]    AnyKindTest    ::=    "node" "(" ")"

The semantics of SequenceTypes is defined by means of normalization rules from SequenceTypes into types in the [XPath/XQuery] type system (See [2.4 The [XPath/XQuery] Type System]).

However, the [XPath/XQuery] type system not being part of the [XPath/XQuery] syntax, the SequenceType syntax is still part of the [XPath/XQuery] Core. Normalization from SequenceTypes to types is not applied during the normalization phase but whenever a dynamic evaluation or static typing rule requires it.

3.5.4 SequenceType Matching

Introduction

During processing of a query, it is sometimes necessary to determine whether a given value matches a type that was declared using the SequenceType syntax. This process is known as SequenceType matching, and is formally specified in [8.3 Judgments for type matching].

Notation

To define normalization of SequenceTypes to the [XPath/XQuery] type system, the following auxiliary mapping rule is used.

 
[SequenceType]sequencetype
==
Type

specifies that SequenceType is mapped to a Type, in the [XPath/XQuery] type system.

Normalization

OccurenceIndicators are left unchanged when normalizing SequenceTypes into [XPath/XQuery] types. Each kind of SequenceType component is normalized separately into the [XPath/XQuery] type system.

 
[ItemType OccurrenceIndicator]sequencetype
==
[ItemType]sequencetype OccurrenceIndicator

The "empty-sequence()" sequence type is mapped to the empty type.

 
[empty-sequence()]sequencetype
==
empty

An atomic type is normalized to itself in the [XPath/XQuery] type system.

 
[AtomicType]sequencetype
==
AtomicType

An "element" SequenceType without content or with a wildcard and no type name is normalized into a wildcard element type.

 
[element()]sequencetype
==
element * of type xs:anyType
 
[element(*)]sequencetype
==
element * of type xs:anyType

An "element" SequenceType with a wildcard and a type name is normalized into a wildcard element type with a corresponding type name. The presence of a "?" after the type name indicates a nillable element.

 
[element(*,TypeName)]sequencetype
==
element * of type TypeName
 
[element(*,TypeName?)]sequencetype
==
element * nillable of type TypeName

An "element" SequenceType with a name and a type name is normalized into an element type with a corresponding type name. The presence of a "?" after the type name indicates a nillable element.

 
[element(ElementName,TypeName)]sequencetype
==
element ElementName of type TypeName
 
[element(ElementName,TypeName?)]sequencetype
==
element ElementName nillable of type TypeName

An "element" SequenceType with only a name is normalized into a nillable element type with a corresponding name. The reason for the normalization to allow nillable elements is because the semantics of SequenceTypes in that case allows it to match every possible element with that names, regardless of its type or nilled property.

 
[element(ElementName)]sequencetype
==
element ElementName nillable of type xs:anyType

A "schema-element" SequenceType with an element declaration is normalized into a reference to the corresponding global element declaration.

 
[schema-element(ElementName)]sequencetype
==
element ElementName

An "attribute" SequenceType without content or with a wildcard and no type name is normalized into a wildcard attribute type.

 
[attribute()]sequencetype
==
attribute * of type xs:anySimpleType
 
[attribute(*)]sequencetype
==
attribute * of type xs:anySimpleType

An "attribute" SequenceType with a wildcard and a type name is normalized into a wildcard attribute type with a corresponding type name.

 
[attribute(*,TypeName)]sequencetype
==
attribute * of type TypeName

An "attribute" SequenceType with a name and a type name is normalized into an attribute type with a corresponding type name.

 
[attribute(AttributeName,TypeName)]sequencetype
==
attribute AttributeName of type TypeName

A "schema-attribute" SequenceType with an attribute declaration is normalized into a reference to the corresponding global attribute declaration.

 
[schema-attribute(AttributeName)]sequencetype
==
attribute AttributeName

A "document-node()" sequence types is normalized into the corresponding document type.

 
[document-node()]sequencetype
==
document { (element * of type xs:anyType | text | comment | processing-instruction)* }

A "document-node" sequence type with an element test (resp. a schema element test) is normalized into the corresponding document type, whose content is the normalization of the element test (resp. schema element test), interleaved with an arbitrary sequence of processing instruction, comment, and text nodes.

 
[document-node(ElementTest)]sequencetype
==
document { [ElementTest]sequencetype & ( processing-instruction | comment ) *}
 
[document-node(SchemaElementTest)]sequencetype
==
document { [SchemaElementTest]sequencetype & ( processing-instruction | comment ) *}

A "processing-instruction()" SequenceType is normalized into the corresponding processing-instruction type.

 
[processing-instruction()]sequencetype
==
processing-instruction

The [XPath/XQuery] type system does not model the target of a processing-instruction, which is treated as a dynamic property. Therefore a "processing-instruction" SequenceType with a string or NCName parameter is normalized into an optional processing-instruction type.

 
[processing-instruction(StringLiteral)]sequencetype
==
processing-instruction?
 
[processing-instruction(NCName)]sequencetype
==
processing-instruction?

A "comment()" SequenceType is normalized into the corresponding comment type.

 
[comment()]sequencetype
==
comment

A "text()" SequenceType is normalized into the corresponding text type.

 
[text()]sequencetype
==
text

The "node()" SequenceType denotes any node. It is normalized into a choice between the corresponding wildcard types for each kind of node.

 
[node()]sequencetype
==
(element * of type xs:anyType | attribute * of type xs:anySimpleType | text | document { (element * of type xs:anyType | text | comment | processing-instruction)* } | comment | processing-instruction)

The "item()" SequenceType denotes any node or atomic value. It is normalized into a choice between the corresponding wildcard types for each kind of nodes or atomic values.

 
[item()]sequencetype
==
(element * of type xs:anyType | attribute * of type xs:anySimpleType | text | document { (element * of type xs:anyType | text | comment | processing-instruction)* } | comment | processing-instruction | xs:anyAtomicType )

3.6 Comments

[151 (XQuery)]    CommentXQ    ::=    "(:" (CommentContents | Comment)* ":)"
[159 (XQuery)]    CommentContentsXQ    ::=    (Char+ - (Char* ('(:' | ':)') Char*))

Comments are lexical constructs only, and have no effect on the meaning of the query, and therefore do not have any formal semantics.

3.7 XML-defined Terminals

The following terminals are defined by XML.

[152 (XQuery)]    PITargetXQ    ::=    [http://www.w3.org/TR/REC-xml#NT-PITarget]XML
[153 (XQuery)]    CharRefXQ    ::=    [http://www.w3.org/TR/REC-xml#NT-CharRef]XML
[154 (XQuery)]    QNameXQ    ::=    [http://www.w3.org/TR/REC-xml-names/#NT-QName]Names
[155 (XQuery)]    NCNameXQ    ::=    [http://www.w3.org/TR/REC-xml-names/#NT-NCName]Names
[156 (XQuery)]    SXQ    ::=    [http://www.w3.org/TR/REC-xml#NT-S]XML
[157 (XQuery)]    CharXQ    ::=    [http://www.w3.org/TR/REC-xml#NT-Char]XML

4 Expressions

This section gives the semantics of all the [XPath/XQuery] expressions. The organization of this section parallels the organization of Section 3 ExpressionsXQ.

[31 (XQuery)]    ExprXQ    ::=    ExprSingle ("," ExprSingle)*
[32 (XQuery)]    ExprSingleXQ    ::=    FLWORExpr
| QuantifiedExpr
| TypeswitchExpr
| IfExpr
| OrExpr
[1 (XPath)]    XPathXP    ::=    Expr

For each expression, a short description and the relevant grammar productions are given. The semantics of an expression includes the normalization, static analysis, and dynamic evaluation phases. Recall that normalization rules translate [XPath/XQuery] syntax into Core syntax. In the sections that contain normalization rules, the Core grammar productions into which the expression is normalized are also provided. After normalization, sections on static type inference and dynamic evaluation define the static type and dynamic value for the Core expression.

Core Grammar

The Core grammar productions for expressions are:

[22 (Core)]    Expr    ::=    ExprSingle ("," ExprSingle)*
[23 (Core)]    ExprSingle    ::=    FLWORExpr
| QuantifiedExpr
| TypeswitchExpr
| IfExpr
| OrExpr

Static Type Analysis

During static analysis, it is a type error for an expression to have the empty type, except for the following expressions and function calls:

The reason for these exceptions is that they are typically part of the result of normalizing a larger user-level expression and are used to capture the semantics of the user-level expression when applied to the empty sequence.

The rule below enforces the above constraints. It is a static type error, if the following conditions hold for a given expression Expr.

statEnv |-  Expr : Type
statEnv |-  Type <: empty
not(Expr is the empty parentheses () or fn:data or any fs function applied to empty parentheses ())

A static type error is raised for expression Expr

In general, static type errors are raised whenever there is no static typing rules which can compute the type of a given expression. This is the reason for the absence of a formal post-condition in this rules. There is indeed a rule that infers the type for expression Expr, however the inferred type is empty and still a static type error must be raised.

Example

The above rule is useful in catching common mistakes, such as the misspelling of an element or attribute name or referencing of an element or attribute that does not exist. For instance, the following path expression

  $x/title

raises a static type error if the type of variable $x does not include any title children elements.

4.1 Primary Expressions

Primary expressions are the basic primitives of the language. They include literals, variables, function calls, and the parenthesized expressions.

Primary Expressions
[84 (XQuery)]    PrimaryExprXQ    ::=    Literal | VarRef | ParenthesizedExpr | ContextItemExpr | FunctionCall | OrderedExpr | UnorderedExpr | Constructor

Core Grammar

The Core grammar production for primary expressions is:

Primary Expressions
[55 (Core)]    PrimaryExpr    ::=    Literal | VarRef | ParenthesizedExpr | FunctionCall | OrderedExpr | UnorderedExpr | Constructor

4.1.1 Literals

Introduction

A literal is a direct syntactic representation of an atomic value. [XPath/XQuery] supports two kinds of literals: string literals and numeric literals.

Literals
[85 (XQuery)]    LiteralXQ    ::=    NumericLiteral | StringLiteral
[86 (XQuery)]    NumericLiteralXQ    ::=    IntegerLiteral | DecimalLiteral | DoubleLiteral
[141 (XQuery)]    IntegerLiteralXQ    ::=    Digits
[142 (XQuery)]    DecimalLiteralXQ    ::=    ("." Digits) | (Digits "." [0-9]*)
[143 (XQuery)]    DoubleLiteralXQ    ::=    (("." Digits) | (Digits ("." [0-9]*)?)) [eE] [+-]? Digits
[144 (XQuery)]    StringLiteralXQ    ::=    ('"' (PredefinedEntityRef | CharRef | EscapeQuot | [^"&])* '"') | ("'" (PredefinedEntityRef | CharRef | EscapeApos | [^'&])* "'")
[140 (XQuery)]    URILiteralXQ    ::=    StringLiteral
[145 (XQuery)]    PredefinedEntityRefXQ    ::=    "&" ("lt" | "gt" | "amp" | "quot" | "apos") ";"
[158 (XQuery)]    DigitsXQ    ::=    [0-9]+

Core Grammar

The Core grammar productions for literals are:

Literals
[56 (Core)]    Literal    ::=    NumericLiteral | StringLiteral
[57 (Core)]    NumericLiteral    ::=    IntegerLiteral | DecimalLiteral | DoubleLiteral
[98 (Core)]    IntegerLiteral    ::=    Digits
[99 (Core)]    DecimalLiteral    ::=    ("." Digits) | (Digits "." [0-9]*)
[100 (Core)]    DoubleLiteral    ::=    (("." Digits) | (Digits ("." [0-9]*)?)) [eE] [+-]? Digits
[101 (Core)]    StringLiteral    ::=    ('"' (EscapeQuot | [^"])* '"') | ("'" (EscapeApos | [^'])* "'")
[97 (Core)]    URILiteral    ::=    StringLiteral
[112 (Core)]    Digits    ::=    [0-9]+

Notation

To define the dynamic semantics of literals, we introduce the following auxiliary judgments.

The judgment

dynEnv |-  Literal has atomic value AtomicValue

holds if the literal expression Literal corresponds to the value AtomicValue. This judgment yields an atomic value, according to the rules described in [XQuery 1.0: An XML Query Language]. Notably, this judgment deals with handling of literal overflows for numeric literals, and handling of character references, and predefined entity references for string literals.

Normalization

Literals are left unchanged through normalization.

 
[IntegerLiteral]Expr
==
IntegerLiteral
 
[DecimalLiteral]Expr
==
DecimalLiteral
 
[DoubleLiteral]Expr
==
DoubleLiteral
 
[StringLiteral]Expr
==
StringLiteral

Static Type Analysis

The static type of a literal expression is its corresponding atomic type.


statEnv |-  IntegerLiteral : xs:integer


statEnv |-  DecimalLiteral : xs:decimal


statEnv |-  DoubleLiteral : xs:double


statEnv |-  StringLiteral : xs:string

Dynamic Evaluation

In the dynamic semantics, a literal is evaluated by constructing an atomic value in the data model, using the has atomic value judgment defined above.

dynEnv |-  Literal has atomic value AtomicValue

dynEnv |-  Literal => AtomicValue

4.1.2 Variable References

Introduction

A variable evaluates to the value to which the variable's QName is bound in the dynamic context.

Variable References
[87 (XQuery)]    VarRefXQ    ::=    "$" VarName
[88 (XQuery)]    VarNameXQ    ::=    QName

Core Grammar

The Core grammar productions for variable references are:

Primary Expressions
[58 (Core)]    VarRef    ::=    "$" VarName
[59 (Core)]    VarName    ::=    QName

Normalization

Variable references are left unchanged through normalization.

 
[VarRef]Expr
==
VarRef

Static Type Analysis

In the static semantics, the type of a variable is simply its type in the static environment statEnv.varType:

statEnv |-  VarName of var expands to Variable
statEnv.varType(Variable) = Type

statEnv |-  $VarName : Type

If the variable is not bound in the static environment, a static type error is raised.

Dynamic Evaluation

In the dynamic semantics, a locally declared variable is evaluated by "looking up" its value in dynEnv.varValue:

statEnv |-  VarName of var expands to Variable
dynEnv.varValue(Variable) = Value

dynEnv |-  $VarName => Value

In the dynamic semantics, a reference to a variable imported from a module is evaluated by accessing the dynamic context of the module in which the variable is declared.

The notation AnyURI =>module_dynEnv dynEnv1 is used to access a module context and is defined in [5.2 Module Declaration].

statEnv |-  VarName of var expands to Variable
dynEnv.varValue(Variable) = #IMPORTED(AnyURI)
AnyURI =>module_dynEnv dynEnv1
dynEnv1.varValue(Variable) = Value

dynEnv |-  $VarName => Value

4.1.3 Parenthesized Expressions

[89 (XQuery)]    ParenthesizedExprXQ    ::=    "(" Expr? ")"

Core Grammar

The Core grammar production for parenthesized expressions is:

[60 (Core)]    ParenthesizedExpr    ::=    "(" Expr? ")"

Empty parentheses () always have the empty type. Remember that it is a static type error for most expressions other than () to have the empty type (see [4 Expressions] for the complete rule.)

Static Type Analysis


statEnv |-  () : empty

statEnv |-  Expr : Type

statEnv |-  ( Expr ) : Type

Dynamic Evaluation

Empty parentheses () evaluate to the empty sequence.


dynEnv |-  () => ()

dynEnv |-  Expr => Value

dynEnv |-  ( Expr ) => Value

4.1.4 Context Item Expression

[90 (XQuery)]    ContextItemExprXQ    ::=    "."

Introduction

A context item expression evaluates to the context item, which may be either a node or an atomic value.

Normalization

A context item expression is normalized to the built-in variable $fs:dot. Because it can only be bound through the external context or a path expression, there is no need for a specific static typing rule to enforce that its value is a singleton item.

 
[.]Expr
==
$fs:dot

4.1.5 Function Calls

Introduction

A function call consists of a QName followed by a parenthesized list of zero or more expressions. In [XPath/XQuery], the actual argument to a function is called an argument and the formal argument of a function is called a parameter. We use the same terminology here.

Function Calls
[93 (XQuery)]    FunctionCallXQ    ::=    QName "(" (ExprSingle ("," ExprSingle)*)? ")"

Because [XPath/XQuery] implicitly converts the values of function arguments, a normalization step is required.

Core Grammar

The Core grammar production for function calls is:

Function Calls
[63 (Core)]    FunctionCall    ::=    QName "(" (ExprSingle ("," ExprSingle)*)? ")"

Notation

Normalization of function calls uses an auxiliary mapping []FunctionArgument(Type) used to insert conversions of function arguments that depend only on the expected Type of the corresponding parameters. It is defined as follows:

 
[Expr]FunctionArgument(Type)
==
[[[Expr]Expr]AtomizeAtomic(Type)]Convert(Type)

where

  • [Expr]AtomizeAtomic(Type) denotes

    If Type <: xs:anyAtomicType*
    Then fn:data(Expr)   
    Else Expr   

    which specifies that if the function expects atomic parameters, then fn:data is called to obtain them.

  • [Expr]Convert(Type) denotes

    If Type <: xs:anyAtomicType*
    Then fs:convert-simple-operand(Expr,PrototypicalValue)
    Else Expr

    where PrototypicalValue is a built-in atomic value used to encode the expected atomic type (for instance the value 1.0 if the expected type is xs:decimal). A value is used here since [XPath/XQuery] expressions cannot operate directly on types. Which value is chosen does not have any impact on the actual semantics, only its actual atomic type matters.

Note

The fs:convert-simple-operand function takes a PrototypicalValue, which is a value of the target type, to ensure that conversion to base types is possible even though types are not first class objects in [XPath/XQuery]. Also, note that in the case of built-in functions where the expected type is specified as numeric, the prototypical value is a value of type xs:double.

Normalization

Each argument expression in a function call is normalized to its corresponding Core expression by applying []FunctionArgument(Type) for each argument with the expected SequenceType for the argument inserted.

statEnv |-  QName of func expands to expanded-QName
statEnv.typeDefn(expanded-QName) = define type QName2 AtomicTypeDerivation
statEnv.funcType(expanded-QName,n) = declare function expanded-QName(Type1, ..., Typen) as Type

statEnv |-  [QName (Expr1, ..., Exprn)]Expr = QName ( [Expr1]FunctionArgument(Type1), ..., [Exprn]FunctionArgument(Typen) )

 
==
QName ( [Expr1]FunctionArgument(Type1), ..., [Exprn]FunctionArgument(Typen) )

Note that this normalization rule depends on the function signatures, which is used to get the types of the function parameters (SequenceType1,...,SequenceTypen). For user-defined functions, the function signature can be obtained from the XQuery prolog where the function is declared. For built-in functions, the signature is given in the [Functions and Operators] document. For overloaded built-in functions, several signatures may exists, however, because they all correspond to sequences of atomic values, they all result in the same normalization.

Static Type Analysis

Different sets of static typing rules are used to type check function calls depending on which of the following categories the belong to: overloaded internal functions, built-in functions with a specific static typing rule, and other built-in and user-defined functions.

The following two rules are common to all those categories, and are used to bootstrap type inference, by first looking-up the expanded QName for the function, then applying the appropriate set of static typing rules depending on the category in which the function is.

statEnv |-  QName of func expands to expanded-QName
statEnv  |-  expanded-QName() : Type

statEnv  |-  QName() : Type

statEnv |-  QName of func expands to expanded-QName
statEnv |-  Expr1 : Type1
...
statEnv |-  Exprn : Typen
statEnv  |-  expanded-QName(Type1,...,Typen) : Type

statEnv  |-  QName (Expr1,...,Exprn) : Type

The following depends on the kind of function call.

  1. If the expanded QName for the function corresponds to one of the overloaded internal fs: functions listed in [C.2 Mapping of Overloaded Internal Functions], the static typing rules in [C.2 Mapping of Overloaded Internal Functions] are applied.

  2. If the expanded QName for the function corresponds to one of the built-in functions with a specialized static typing rule, listed in [7 Additional Semantics of Functions], the static typing rules in [7 Additional Semantics of Functions] are applied.

  3. Otherwise, the following general static typing rules are applied.

The two following rules look up the function in the static environment and check that some signature for the function satisfies the following constraint: the type of each actual argument is a subtype of some type that can be promoted to the type of the corresponding function parameter. In this case, the function call is well typed and the result type is the return type specified in the function's signature.

statEnv.funcType(expanded-QName,0) = declare function expanded-QName() as Type'

statEnv  |-  expanded-QName() : Type'

statEnv.funcType(expanded-QName,n) = declare function expanded-QName(Type1', ..., Typen') as Type'
statEnv  |-  Type1 can be promoted to Type1'
...
statEnv  |-  Typen can be promoted to Typen'

statEnv  |-  expanded-QName(Type1, ..., Typen) : Type'

The function body itself is not analyzed for each invocation: static typing of the function definition itself guarantees that the function body always returns a value of the declared return type.

Notice that the static context contains at most one function declaration for each function. This is possible since the treatment of overloaded operators is done through a set of specific static typing rules which do not require access to the environment. See [C.2 Mapping of Overloaded Internal Functions].

Notation

The following auxiliary judgment

dynEnv |-  function expanded-QName with types on values yields Value

holds when applying the function with expanded QName expanded-QName and no parameter yields the value Value.

dynEnv |-  function expanded-QName with types (Type1,...,Typen) on values (Value1,...,Valuen) yields Value

holds when applying the function with expanded QName expanded-QName, and parameters of type (Type1,...,Typen) on the values (Value1,...,Valuen) yields the value Value.

That judgment is defined below for each kind of function (user-defined, built-in, external, and imported functions).

Dynamic Evaluation

The following rules apply to all the different kinds of functions using the previously defined judgment.

statEnv |-  QName of func expands to expanded-QName
statEnv.funcType(expanded-QName) = FunctionSig
FunctionSig = declare function expanded-QName() as Type
dynEnv |-  function expanded-QName with types on values yields Value
statEnv |-  Value against Type promotes to Value'

dynEnv  |-  QName() => Value'

dynEnv |-  Expr1 => Value1
...
dynEnv |-  Exprn => Valuen
statEnv |-  QName of func expands to expanded-QName
statEnv.funcType(expanded-QName) = FunctionSig
FunctionSig = declare function expanded-QName(Type1, ..., Typen) as Type
statEnv |-  Value1 against Type1 promotes to Value1'
...
statEnv |-  Valuen against Typen promotes to Valuen'
dynEnv |-  function expanded-QName with types (Type1,...,Typen) on values (Value1',...,Valuen') yields Value
statEnv |-  Value against Type promotes to Value'

dynEnv  |-  QName ( Expr1, ..., Exprn ) => Value'

First the function name is expanded, and the expanded name is used to retrieve the function signature from the static environment. Then, the rule evaluates each function argument expression, and the resulting values are promoted according to the expected type for the function. The result of evaluating the function is obtained through the auxiliary judgment previously defined, and the resulting value is promoted according to the expected return type.

In case the function is a user defined function in a main module, the expression body is retrieved from the dynamic environment and used to compute the value of the function. The rule extends dynEnv.varValue by binding each formal variable to its corresponding value, and evaluates the body of the function in the new environment. The resulting value is the value of the function call.

The notation AnyURI =>module_dynEnv dynEnv1 is used to access a module context and is defined in [5.2 Module Declaration].

dynEnv.funcDefn(expanded-QName() = (Expr)
#MAIN =>module_dynEnv dynEnv1
dynEnv1.varValue |-  Expr => Value

dynEnv |-  function expanded-QName with types on values yields Value

dynEnv.funcDefn(expanded-QName(Type1, ..., Typen)) = (Expr, Variable1, ... , Variablen)
#MAIN =>module_dynEnv dynEnv1
dynEnv1 + varValue( Variable1 => Value1; ...; Variablen => Valuen)  |-  Expr => Value

dynEnv |-  function expanded-QName with types (Type1,...,Typen) on values (Value1,...,Valuen) yields Value

Note that the function body is evaluated in the dynamic environment containing the main module declarations.

The rule for evaluating an function imported from a module is similar to that for evaluating a user-defined function in a main module, except that the function call is evaluated in the dynamic context of the module in which it is declared, and that the appropriate additional type matching must be performed.

dynEnv.funcDefn(expanded-QName()) = #IMPORTED(AnyURI)
AnyURI =>module_statEnv statEnv1
AnyURI =>module_dynEnv dynEnv1
statEnv.funcType1(expanded-QName) = FunctionSig'
FunctionSig' = declare function expanded-QName() as Type'
dynEnv1.funcDefn(expanded-QName() = (Expr)
dynEnv1.varValue |-  Expr => Value
statEnv |-  Value matches Type'

dynEnv |-  function expanded-QName with types on values yields Value

dynEnv.funcDefn(expanded-QName(Type1, ..., Typen)) = #IMPORTED(AnyURI)
AnyURI =>module_statEnv statEnv1
AnyURI =>module_dynEnv dynEnv1
statEnv.funcType1(expanded-QName) = FunctionSig'
FunctionSig' = declare function expanded-QName(Type1', ..., Typen') as Type'
statEnv |-  Value1 matches Type1'
...
statEnv |-  Valuen matches Typen'
dynEnv1.funcDefn(expanded-QName(Type1', ..., Typen')) = (Expr, Variable1, ... , Variablen)
dynEnv1 + varValue( Variable1 => Value1; ...; Variablen => Valuen)  |-  Expr => Value
statEnv |-  Value matches Type'

dynEnv |-  function expanded-QName with types (Type1,...,Typen) on values (Value1,...,Valuen) yields Value

If the function is a built-in function (resp. special formal semantics function), the value returned by the function is the one specified in [Functions and Operators] (resp. [7 Additional Semantics of Functions]).

dynEnv.funcDefn(expanded-QName()) = #BUILT-IN
The built-in function expanded-QName (See [Functions and Operators] or [7 Additional Semantics of Functions]) yields the value Value

dynEnv |-  function expanded-QName with types on values yields Value

dynEnv.funcDefn(expanded-QName(Type1, ..., Typen)) = #BUILT-IN
The built-in function expanded-QName (See [Functions and Operators] or [7 Additional Semantics of Functions]) applied to values (Value1,...,Valuen) yields the value Value

dynEnv |-  function expanded-QName with types (Type1,...,Typen) on values (Value1,...,Valuen) yields Value

If the function is an external function, the value returned by the function is implementation-defined.

dynEnv.funcDefn(expanded-QName()) = #EXTERNAL
The external function expanded-QName yields the value Value

dynEnv |-  function expanded-QName with types on values yields Value

dynEnv.funcDefn(expanded-QName(Type1, ..., Typen)) = #EXTERNAL
The external function expanded-QName applied to values (Value1,...,Valuen) yields the value Value

dynEnv |-  function expanded-QName with types (Type1,...,Typen) on values (Value1,...,Valuen) yields Value

4.2 Path Expressions

Introduction

Path expressions are used to locate nodes within a tree. There are two kinds of path expressions, absolute path expressions and relative path expressions. An absolute path expression is a rooted relative path expression. A relative path expression is composed of a sequence of steps.

Path Expressions
[68 (XQuery)]    PathExprXQ    ::=    ("/" RelativePathExpr?)
| ("//" RelativePathExpr)
| RelativePathExpr
[69 (XQuery)]    RelativePathExprXQ    ::=    StepExpr (("/" | "//") StepExpr)*

Core Grammar

PathExpr and RelativePathExpr are fully normalized, therefore they have no corresponding productions in the Core. The grammar for path expressions in the Core starts with the StepExpr production.

Normalization

Absolute path expressions are path expressions starting with the / or // symbols, indicating that the expression must be applied on the root node in the current context. The root node in the current context is the greatest ancestor of the context node. The following two rules normalize absolute path expressions to relative ones. They use the fn:root function, which returns the greatest ancestor of its argument node. The treat expressions guarantee that the value bound to the context variable $fs:dot is a document node.

 
[/]Expr
==
[(fn:root(self::node()) treat as document-node())]Expr
 
[/ RelativePathExpr]Expr
==
[((fn:root(self::node())) treat as document-node()) / RelativePathExpr]Expr
 
[// RelativePathExpr]Expr
==
[((fn:root(self::node())) treat as document-node()) / descendant-or-self::node() / RelativePathExpr]Expr
 
[RelativePathExpr // StepExpr ]Expr
==
[RelativePathExpr / descendant-or-self::node() / StepExpr]Expr

A composite relative path expression (using /) is normalized into a for expression by concatenating the sequences obtained by mapping each node of the left-hand side in document order to the sequence it generates on the right-hand side. The call to the fs:distinct-doc-order function ensures that the result is in document order without duplicates. The dynamic context is defined by binding the $fs:dot, $fs:sequence, $fs:position and $fs:last variables.

Note that sorting by document order enforces the restriction that input and output sequences contains only nodes, and that the last step in a path expression may actually return atomic values.

 
[RelativePathExpr / StepExpr]Expr
==
fs:apply-ordering-mode (
fs:distinct-doc-order-or-atomic-sequence (
  let $fs:sequence as node()* := [RelativePathExpr]Expr return
  let $fs:last := fn:count($fs:sequence) return
  for $fs:dot at $fs:position in $fs:sequence return
    [StepExpr]Expr
))

4.2.1 Steps

Note that this section uses some auxiliary judgments which are defined in [8.2 Judgments for step expressions and filtering].

Introduction

Steps
[70 (XQuery)]    StepExprXQ    ::=    FilterExpr | AxisStep
[71 (XQuery)]    AxisStepXQ    ::=    (ReverseStep | ForwardStep) PredicateList
[72 (XQuery)]    ForwardStepXQ    ::=    (ForwardAxis NodeTest) | AbbrevForwardStep
[75 (XQuery)]    ReverseStepXQ    ::=    (ReverseAxis NodeTest) | AbbrevReverseStep
[82 (XQuery)]    PredicateListXQ    ::=    Predicate*

Core Grammar

The Core grammar productions for XPath steps are:

Steps
[46 (Core)]    StepExpr    ::=    PrimaryExpr | AxisStep
[47 (Core)]    AxisStep    ::=    ReverseStep | ForwardStep
[48 (Core)]    ForwardStep    ::=    ForwardAxis NodeTest
[50 (Core)]    ReverseStep    ::=    ReverseAxis NodeTest

Note

Step expressions can be followed by predicates. Normalization of predicates uses the following auxiliary mapping rule: []Predicates, which is specified in [4.2.2 Predicates]. Normalization for step expressions also uses the following auxiliary mapping rule: []Axis, which is specified in [4.2.1.1 Axes].

Normalization

Normalization of predicates need to distinguish between forward steps, reverse steps, and primary expressions.

As explained in the [XPath/XQuery] document, applying a step in XPath changes the focus (or context). The change of focus is made explicit by the normalization rule below, which binds the variable $fs:dot to the node currently being processed, and the variable $fs:position to the position (i.e., the position within the input sequence) of that node.

There are two sets of normalization rules for Predicates. The first set of rules apply when the predicate is a numeric literal or the expression last(). The second set of rules apply to all predicate expressions other than numeric literals and the expression last(). In the first case, the normalization rules provides a more precise static type than if the general rules were applied.

When the predicate expression is a numeric literal or the fn:last function, the following normalization rules apply.

 
[ForwardStep PredicateList [ NumericLiteral ]]Expr
==
let $fs:sequence := fs:apply-ordering-mode(fs:distinct-doc-order( [ForwardStep PredicateList]Expr )) return
fn:subsequence($fs:sequence,NumericLiteral,1)
 
[ForwardStep PredicateList [ fn:last() ]]Expr
==
let $fs:sequence := fs:apply-ordering-mode(fs:distinct-doc-order( [ForwardStep PredicateList]Expr )) return
let $fs:last := fn:count($fs:sequence) return
fn:subsequence($fs:sequence,$fs:last,1)

When predicates are applied on a reverse step, the position variable is bound in reverse document order.

 
[ReverseStep PredicateList [ NumericLiteral ]]Expr
==
let $fs:sequence := fs:apply-ordering-mode(fs:distinct-doc-order( [ReverseStep PredicateList]Expr )) return
let $fs:last := fn:count($fs:sequence) return
let $fs:position := $fs:last - NumericLiteral + 1 return
  fn:subsequence($fs:sequence,$fs:position,1)

When the step is a reverse axis, then the last item in the context sequence is the first in document order.

 
[ReverseStep PredicateList [ fn:last() ]]Expr
==
let $fs:sequence := fs:apply-ordering-mode(fs:distinct-doc-order( [ReverseStep PredicateList]Expr )) return
  fn:subsequence($fs:sequence,1,1)

The normalization rules above all use the function fn:subsequence to select a particular item. The static typing rules for this function are defined in [7.2.13 The fn:subsequence function].

When predicates are applied on a forward step, the input sequence is first sorted in document order and duplicates are removed. The context is changed by binding the $fs:dot variable to each node in document order.

 
[ForwardStep PredicateList [ Expr ]]Expr
==
let $fs:sequence := fs:apply-ordering-mode(fs:distinct-doc-order( [ForwardStep PredicateList]Expr )) return
let $fs:last := fn:count($fs:sequence) return
for $fs:dot at $fs:position in $fs:sequence return
   if [Expr]Predicates then $fs:dot else ()

When predicates are applied on a reverse step, the input sequence is first sorted in document order and duplicates are removed. The context is changed by binding the $fs:dot variable to each node in document order.

 
[ReverseStep PredicateList [ Expr ]]Expr
==
let $fs:sequence := fs:apply-ordering-mode(fs:distinct-doc-order( [ReverseStep PredicateList]Expr )) return
let $fs:last := fn:count($fs:sequence) return
for $fs:dot at $fs:new in $fs:sequence return
let $fs:position := $fs:last - $fs:new + 1 return
  if [Expr]Predicates then $fs:dot else ()

Finally, a stand-alone forward or reverse step is normalized by the auxiliary normalization rule for Axis.

 
[ForwardStep]Expr
==
fs:apply-ordering-mode([ForwardStep]Axis)
 
[ReverseStep]Expr
==
fs:apply-ordering-mode([ReverseStep]Axis)

Static Type Analysis

The static semantics of an Axis NodeTest pair is obtained by retrieving the type of the context node, and applying the two filters (the Axis, and then the NodeTest with a PrincipalNodeKind) on the result.

statEnv.varType((FS-URI,"dot")) = Type1
statEnv  |-  Type1 <: [node()]sequencetype
statEnv |-  axis Axis of Type1 : Type2
Axis has principal PrincipalNodeKind
statEnv |-  test NodeTest with PrincipalNodeKind of Type2 : Type3

statEnv |-  Axis NodeTest : Type3

Note

Note that the second judgment in the rule requires that the context item be a node, guaranteeing that a type error is raised when the context item is an atomic value.

Dynamic Evaluation

The dynamic semantics of an Axis NodeTest pair is obtained by retrieving the context node, and applying the two filters (Axis, then NodeTest) on the result. The application of each filter is expressed through several auxiliary judgments (of, has principal, and test), as follows.

dynEnv.varValue($fs:dot) = Value1
statEnv  |-  Value1 matches node
dynEnv |-  axis Axis of Value1 => Value2
Axis has principal PrincipalNodeKind
dynEnv |-  test NodeTest with PrincipalNodeKind of Value2 => Value3

dynEnv |-  Axis NodeTest => fs:distinct-doc-order(Value3)

Note

Note that the second judgment in the rule guarantees that the context item is bound to a node.

4.2.1.1 Axes

Introduction

The XQuery grammar for forward and reverse axis is as follows.

Axes
[73 (XQuery)]    ForwardAxisXQ    ::=    ("child" "::")
| ("descendant" "::")
| ("attribute" "::")
| ("self" "::")
| ("descendant-or-self" "::")
| ("following-sibling" "::")
| ("following" "::")
[76 (XQuery)]    ReverseAxisXQ    ::=    ("parent" "::")
| ("ancestor" "::")
| ("preceding-sibling" "::")
| ("preceding" "::")
| ("ancestor-or-self" "::")

In the case of XPath, forward axis also contain the namespace:: axis.

Axes
[30 (XPath)]    ForwardAxisXP    ::=    ("child" "::")
| ("descendant" "::")
| ("attribute" "::")
| ("self" "::")
| ("descendant-or-self" "::")
| ("following-sibling" "::")
| ("following" "::")
| ("namespace" "::")

Core Grammar

The Core grammar productions for XPath axis are:

Axes
[49 (Core)]    ForwardAxis    ::=    ("child" "::")
| ("descendant" "::")
| ("attribute" "::")
| ("self" "::")
| ("descendant-or-self" "::")
| ("namespace" "::")
[51 (Core)]    ReverseAxis    ::=    ("parent" "::")
| ("ancestor" "::")
| ("ancestor-or-self" "::")

Notation

The normalization of axes uses the following auxiliary mapping rule: []Axis.

Normalization

The normalization for all axes is specified as follows.

The semantics of the following(-sibling) and preceding(-sibling) axes are expressed by mapping them to Core expressions. All other axes are part of the Core and therefore are left unchanged through normalization.

 
[following-sibling:: NodeTest]Axis
==
[let $e := . return $e/parent::node()/child:: NodeTest [.>>$e]]Expr
 
[following:: NodeTest]Axis
==
[ancestor-or-self::node()/following-sibling::node()/descendant-or-self::NodeTest]Expr

All other forward axes are part of the Core [XPath/XQuery] and handled by the normalization rules below:

 
[child:: NodeTest]Axis
==
child:: NodeTest
 
[attribute:: NodeTest]Axis
==
attribute:: NodeTest
 
[self:: NodeTest]Axis
==
self:: NodeTest
 
[descendant:: NodeTest]Axis
==
descendant:: NodeTest
 
[descendant-or-self:: NodeTest]Axis
==
descendant-or-self:: NodeTest
 
[namespace:: NodeTest]Axis
==
namespace:: NodeTest

Reverse axes:

 
[preceding-sibling:: NodeTest]Axis
==
[let $e := . return $e/parent::node()/child:: NodeTest [.<<$e]]Expr
 
[preceding:: NodeTest]Axis
==
[ancestor-or-self::node()/preceding-sibling::node()/descendant-or-self::NodeTest]Expr

All other reverse axes are part of the Core [XPath/XQuery] and handled by the normalization rules below:

 
[parent:: NodeTest]Axis
==
parent:: NodeTest
 
[ancestor:: NodeTest]Axis
==
ancestor:: NodeTest
 
[ancestor-or-self:: NodeTest]Axis
==
ancestor-or-self:: NodeTest
4.2.1.2 Node Tests

Introduction

A node test is a condition applied on the nodes selected by an axis step. Node tests are described by the following grammar productions.

Node Tests
[78 (XQuery)]    NodeTestXQ    ::=    KindTest | NameTest
[79 (XQuery)]    NameTestXQ    ::=    QName | Wildcard
[80 (XQuery)]    WildcardXQ    ::=    "*"
| (NCName ":" "*")
| ("*" ":" NCName)

Core Grammar

The Core grammar productions for node tests are:

Node Tests
[52 (Core)]    NodeTest    ::=    KindTest | NameTest
[53 (Core)]    NameTest    ::=    QName | Wildcard
[54 (Core)]    Wildcard    ::=    "*"
| (NCName ":" "*")
| ("*" ":" NCName)

Notation

For convenience, we will use the grammar non-terminals Prefix, and LocalPart, both of which are NCNames, in some of the inference rules. They are defined by the following grammar productions.

Prefix and LocalPart
[18 (Formal)]    Prefix    ::=    NCName
[19 (Formal)]    LocalPart    ::=    NCName

4.2.2 Predicates

Introduction

A predicate consists of an expression, called a predicate expression, enclosed in square brackets.

[83 (XQuery)]    PredicateXQ    ::=    "[" Expr "]"

Notation

Normalization of predicates uses the following auxiliary mapping rule: []Predicates.

Normalization

Predicates in path expressions are normalized with a special mapping rule:

 
[Expr]Predicates
==
typeswitch ([Expr]Expr)
  case $v as fs:numeric return op:numeric-equal($v, $fs:position)
  default $v return fn:boolean($v)

Note that the semantics of predicates whose input expression returns a numeric value also work if that value is not an integer. In those cases the op:numeric-equal returns false when compared to a position. For example, the expression //a[3.4] always returns the empty sequence.

4.2.3 Unabbreviated Syntax

The corresponding Section in the [XPath/XQuery] document just contains examples.

4.2.4 Abbreviated Syntax

Abbreviated Syntax
[74 (XQuery)]    AbbrevForwardStepXQ    ::=    "@"? NodeTest
[77 (XQuery)]    AbbrevReverseStepXQ    ::=    ".."

Normalization

Here are normalization rules for the abbreviated syntax.

 
[ .. ]Expr
==
[parent::node()]Axis
 
[ @ NameTest ]Expr
==
attribute :: NameTest
 
[ NodeTest ]Expr
==
[child :: NodeTest]Axis

4.3 Sequence Expressions

Introduction

[XPath/XQuery] supports operators to construct and combine sequences. A sequence is an ordered collection of zero or more items. An item is either an atomic value or a node.

4.3.1 Constructing Sequences

Constructing Sequences
[31 (XQuery)]    ExprXQ    ::=    ExprSingle ("," ExprSingle)*
[49 (XQuery)]    RangeExprXQ    ::=    AdditiveExpr ( "to" AdditiveExpr )?

Core Grammar

The Core grammar production for sequence expressions is:

Core Sequence Expressions
[22 (Core)]    Expr    ::=    ExprSingle ("," ExprSingle)*

Normalization

A sequence expression is normalized into a sequence of normalized single expressions:

 
[Expr1 , Expr2]Expr
==
[Expr1]Expr, [Expr2]Expr

Static Type Analysis

The type of the sequence expression is the sequence over the types of the individual expressions.

statEnv  |-  Expr1 : Type1      statEnv  |-  Expr2 : Type2

statEnv  |-  Expr1 , Expr2 : Type1, Type2

Dynamic Evaluation

Each expression in the sequence is evaluated and the resulting values are concatenated into one sequence.

dynEnv |-  Expr1 => Value1     dynEnv |-  Expr2 => Value2

dynEnv |-  Expr1, Expr2 => Value1, Value2

Normalization

The range operator is normalized to the fs:to function.

 
[Expr1 to Expr2]Expr
==
fs:to(([Expr1]Expr),([Expr2]Expr))

Static Type Analysis

The static semantics of the fs:to function is defined in [7.1.12 The fs:to function].

Dynamic Evaluation

The dynamic semantics of the fs:to function is defined in [7.1.12 The fs:to function].

4.3.2 Filter Expressions

Introduction

Filter Expression
[81 (XQuery)]    FilterExprXQ    ::=    PrimaryExpr PredicateList

Core Grammar

There are no Core grammar productions for filter expressions as they are normalized to other Core expressions.

Normalization

When a predicate with a numeric literal or the last() expression is applied on a primary expression, it is normalized using the fn:subsequence function. This results in a more precise static type for those cases.

 
[PrimaryExpr PredicateList [ NumericLiteral ]]Expr
==
let $fs:sequence := [PrimaryExpr PredicateList]Expr return
fn:subsequence($fs:sequence,NumericLiteral,1)
 
[PrimaryExpr PredicateList [ fn:last() ]]Expr
==
let $fs:sequence := [PrimaryExpr PredicateList]Expr return
fn:subsequence($fs:sequence,$fs:last,1)

In the general case, when a predicate is applied on a primary expression, it is normalized to a FLWOR expression as follows. The input sequence is processed in sequence order and the context item is bound to each item in the input sequence.

 
[PrimaryExpr PredicateList [ Expr ]]Expr
==
let $fs:sequence := [PrimaryExpr PredicateList]Expr return
let $fs:last := fn:count($fs:sequence) return
for $fs:dot at $fs:position in $fs:sequence return
   if ([Expr]Predicates) then $fs:dot else ()

Static Type Analysis

There are no additional static typing rules for filter expressions.

Dynamic Evaluation

There are no additional dynamic evaluation rules for filter expressions.

4.3.3 Combining Node Sequences

[XPath/XQuery] provides several operators for combining sequences of nodes.

Combining Sequences
[52 (XQuery)]    UnionExprXQ    ::=    IntersectExceptExpr ( ("union" | "|") IntersectExceptExpr )*
[53 (XQuery)]    IntersectExceptExprXQ    ::=    InstanceofExpr ( ("intersect" | "except") InstanceofExpr )*

Notation

The union, intersect, and except expressions are normalized into function calls to the appropriate functions. The mapping function []SequenceOp is defined by the following table:

SequenceOp [SequenceOp]SequenceOp
"union" op:union
"|" op:union
"intersect" op:intersect
"except" op:except

Normalization

Operators for combining node sequences are normalized as follows.

 
[Expr1 SequenceOp Expr2]Expr
==
fs:apply-ordering-mode ([SequenceOp]SequenceOp ( [Expr1]Expr, [Expr2]Expr ))

Static Type Analysis

The static semantics of the operators that combine sequences are defined in [7.2.14 The op:union, op:intersect, and op:except operators].

Dynamic Evaluation

The dynamic semantics for function calls is given in [4.1.5 Function Calls].

4.4 Arithmetic Expressions

[XPath/XQuery] provides arithmetic operators for addition, subtraction, multiplication, division, and modulus, in their usual binary and unary forms.

Arithmetic Expressions
[50 (XQuery)]    AdditiveExprXQ    ::=    MultiplicativeExpr ( ("+" | "-") MultiplicativeExpr )*
[51 (XQuery)]    MultiplicativeExprXQ    ::=    UnionExpr ( ("*" | "div" | "idiv" | "mod") UnionExpr )*
[58 (XQuery)]    UnaryExprXQ    ::=    ("-" | "+")* ValueExpr
[59 (XQuery)]    ValueExprXQ    ::=    ValidateExpr | PathExpr | ExtensionExpr

Core Grammar

The Core grammar production for arithmetic expressions is:

[40 (Core)]    ValueExpr    ::=    ValidateExpr | StepExpr | ExtensionExpr

Notation

The mapping functions []ArithOp and UnaryArithOp are defined by the following tables:

ArithOp [ArithOp]ArithOp
"+" fs:plus
"-" fs:minus
"*" fs:times
"div" fs:div
"mod" fs:mod
UnaryArithOp [UnaryArithOp]UnaryArithOp
"+" fs:unary-plus
"-" fs:unary-minus

Core Grammar

There are no Core grammar productions for arithmetic expressions as they are normalized to other Core expressions.

Normalization

The normalization rules for all the arithmetic operators except idiv first atomize each argument by applying fn:data and then apply the internal function fs:convert-operand to each argument. If the first argument to this function has type xs:untypedAtomic, then the first argument is cast to a double, otherwise it is returned unchanged. The overloaded internal function corresponding to the arithmetic operator is then applied to the two converted arguments. The table above maps the operators to the corresponding internal function. The mapping from the overloaded internal functions to the corresponding non-overloaded function is given in [C.2 Mapping of Overloaded Internal Functions].

 
[Expr1 ArithOp Expr2]Expr
==
[ArithOp]ArithOp ( fs:convert-operand(fn:data(([Expr1]Expr)), 1.0E0),
fs:convert-operand(fn:data(([Expr2]Expr)), 1.0E0))

The normalization rules for the idiv operator are similar, but instead of casting arguments with type xs:untypedAtomic to xs:double, they are cast to xs:integer.

 
[Expr1 idiv Expr2]Expr
==
fs:idiv ( fs:convert-operand(fn:data(([Expr1]Expr)), 1),
fs:convert-operand(fn:data(([Expr2]Expr)), 1))

The unary operators are mapped similarly.

 
[+ Expr]Expr
==
fs:unary-plus(fs:convert-operand(fn:data(([Expr]Expr)), 1.0E0))
 
[- Expr]Expr
==
fs:unary-minus(0, fs:convert-operand(fn:data(([Expr]Expr)), 1.0E0))

Static Type Analysis

The static semantics for function calls is given in [4.1.5 Function Calls].

Dynamic Evaluation

The dynamic semantics for function calls is given in [4.1.5 Function Calls].

4.5 Comparison Expressions

Introduction

Comparison expressions allow two values to be compared. [XPath/XQuery] provides three kinds of comparison expressions, called value comparisons, general comparisons, and node comparisons.

Comparison Expressions
[48 (XQuery)]    ComparisonExprXQ    ::=    RangeExpr ( (ValueComp
| GeneralComp
| NodeComp) RangeExpr )?
[61 (XQuery)]    ValueCompXQ    ::=    "eq" | "ne" | "lt" | "le" | "gt" | "ge"
[60 (XQuery)]    GeneralCompXQ    ::=    "=" | "!=" | "<" | "<=" | ">" | ">="
[62 (XQuery)]    NodeCompXQ    ::=    "is" | "<<" | ">>"

4.5.1 Value Comparisons

Notation

The mapping function []ValueOp is defined by the following table:

ValueOp [ValueOp]ValueOp
"eq" fs:eq
"ne" fs:ne
"lt" fs:lt
"le" fs:le
"gt" fs:gt
"ge" fs:ge

Core Grammar

There are no Core grammar productions for value comparisons as they are normalized to other Core expressions.

Normalization

The normalization rules for the value comparison operators first atomize each argument by applying fn:data and then apply the internal function fs:convert-operand defined in [7.1.1 The fs:convert-operand function]. If the first argument to this function has type xs:untypedAtomic, then the first argument is cast to a string, otherwise it is returned unchanged. The overloaded internal function corresponding to the value comparison operator is then applied to the two converted arguments. The table above maps the value operators to the corresponding internal function. The mapping from the overloaded internal functions to the corresponding non-overloaded function is given in [C.2 Mapping of Overloaded Internal Functions].

 
[Expr1 ValueOp Expr2]Expr
==
[ValueOp]ValueOp ( fs:convert-operand(fn:data(([Expr1]Expr)), "string"),
fs:convert-operand(fn:data(([Expr2]Expr)), "string") )

Static Type Analysis

The static semantics for function calls is given in [4.1.5 Function Calls]. The comparison functions all have return type xs:boolean, as specified in [Functions and Operators].

Dynamic Evaluation

The dynamic semantics for function calls is given in [4.1.5 Function Calls].

4.5.2 General Comparisons

Introduction

General comparisons are defined by adding existential semantics to value comparisons. The operands of a general comparison may be sequences of any length. The result of a general comparison is always true or false.

Notation

For convenience, GeneralOp denotes the operators "=", "!=", "<", "<=", ">", or ">=".

The function []GeneralOp is defined by the following table:

GeneralOp [GeneralOp]GeneralOp
"=" fs:eq
"!=" fs:ne
"<" fs:lt
"<=" fs:le
">" fs:gt
">=" fs:ge

Core Grammar

There are no Core grammar productions for general comparisons as they are normalized to existentially quantified Core expressions.

Normalization

The normalization rule for a general comparison expression first atomizes each argument by applying fn:data and then applies the existentially quantified SomeExpr expression to each sequence. The internal function fs:convert-operand is applied to each pair of atomic values. If the first argument to this function has type xs:untypedAtomic, then the first argument is cast to type of the second argument. If the second argument has type xs:untypedAtomic, the first argument is cast to a string. The overloaded internal function corresponding to the general comparison operator is then applied to the two converted values.

 
[Expr1 GeneralOp Expr2]Expr
==
some $v1 in fn:data(([Expr1]Expr)) satisfies
some $v2 in fn:data(([Expr2]Expr)) satisfies
let $u1 := fs:convert-operand($v1, $v2) return
let $u2 := fs:convert-operand($v2, $v1) return
[GeneralOp]GeneralOp ($u1, $u2)

4.5.3 Node Comparisons

Core Grammar

There are no Core grammar productions for node comparisons as they are normalized to other Core expressions.

Normalization

The normalization rules for node comparisons map each argument expression and then apply the internal function corresponding to the node comparison operator. The internal function are defined in [C.2 Mapping of Overloaded Internal Functions].

 
[Expr1 is Expr2]Expr
==
   fs:is-same-node(([Expr1]Expr), ([Expr2]Expr))
 
[Expr1 << Expr2]Expr
==
fs:node-before(([Expr1]Expr), ([Expr2]Expr))
 
[Expr1 >> Expr2]Expr
==
fs:node-after(([Expr1]Expr), ([Expr2]Expr))

Static Type Analysis

The static semantics for the internal functions are defined in [C.2 Mapping of Overloaded Internal Functions].

Dynamic Evaluation

The dynamic semantics for internal function is defined in [C.2 Mapping of Overloaded Internal Functions].

4.6 Logical Expressions

Introduction

A logical expression is either an and-expression or an or-expression. The value of a logical expression is always one of the boolean values: true or false.

Logical Expressions
[46 (XQuery)]    OrExprXQ    ::=    AndExpr ( "or" AndExpr )*
[47 (XQuery)]    AndExprXQ    ::=    ComparisonExpr ( "and" ComparisonExpr )*

Core Grammar

The Core grammar productions for logical expressions are:

Core Logical Expressions
[36 (Core)]    OrExpr    ::=    AndExpr ( "or" AndExpr )*
[37 (Core)]    AndExpr    ::=    CastableExpr ( "and" CastableExpr )*

Normalization

The normalization rules for "and" and "or" first get the effective boolean value of each argument, then apply the appropriate Core operator.

 
[Expr1 and Expr2]Expr
==
fn:boolean(([Expr1]Expr)) and fn:boolean(([Expr2]Expr))
 
[Expr1 or Expr2]Expr
==
fn:boolean(([Expr1]Expr)) or fn:boolean(([Expr2]Expr))

Static Type Analysis

The logical expressions require that each subexpression have type xs:boolean. The result type is also xs:boolean.

statEnv  |-  Expr1 : xs:boolean      statEnv  |-  Exprn : xs:boolean

statEnv  |-  Expr1 and Expr2 : xs:boolean

statEnv  |-  Expr1 : xs:boolean      statEnv  |-  Exprn : xs:boolean

statEnv  |-  Expr1 or Expr2 : xs:boolean

Dynamic Evaluation

The dynamic semantics of logical expressions is non-deterministic. This non-determinism permits implementations to use short-circuit evaluation strategies when evaluating logical expressions. In the expression, Expr1 and Expr2, if either expression raises an error or evaluates to false, the entire expression may raise an error or evaluate to false. In the expression, Expr1 or Expr2, if either expression raises an error or evaluates to true, the entire expression may raise an error or evaluate to true.

dynEnv  |-  Expri => false
i in { 1,2 }

dynEnv  |-  Expr1 and Expr2 => false

dynEnv  |-  Expr1 => true      dynEnv  |-  Expr2 => true

dynEnv  |-  Expr1 and Expr2 => true

dynEnv  |-  Expri => true
i in { 1,2 }

dynEnv  |-  Expr1 or Expr2 => true

dynEnv  |-  Expr1 => false      dynEnv  |-  Expr2 => false

dynEnv  |-  Expr1 or Expr2 => false

4.7 Constructors

[XPath/XQuery] supports two forms of constructors. Direct constructors support literal XML syntax for elements, attributes, text nodes, processing-instructions and comments. Computed constructors can be used to construct elements, attributes, text nodes, processing-instructions, comments, and document nodes. All direct constructors are normalized into computed constructors, i.e., there are no direct-constructor expressions in the Core.

Constructors
[94 (XQuery)]    ConstructorXQ    ::=    DirectConstructor
| ComputedConstructor
[95 (XQuery)]    DirectConstructorXQ    ::=    DirElemConstructor
| DirCommentConstructor
| DirPIConstructor
[96 (XQuery)]    DirElemConstructorXQ    ::=    "<" QName DirAttributeList ("/>" | (">" DirElemContent* "</" QName S? ">"))
[101 (XQuery)]    DirElemContentXQ    ::=    DirectConstructor
| CDataSection
| CommonContent
| ElementContentChar
[148 (XQuery)]    ElementContentCharXQ    ::=    Char - [{}<&]
[102 (XQuery)]    CommonContentXQ    ::=    PredefinedEntityRef | CharRef | "{{" | "}}" | EnclosedExpr
[107 (XQuery)]    CDataSectionXQ    ::=    "<![CDATA[" CDataSectionContents "]]>"
[108 (XQuery)]    CDataSectionContentsXQ    ::=    (Char* - (Char* ']]>' Char*))
[97 (XQuery)]    DirAttributeListXQ    ::=    (S (QName S? "=" S? DirAttributeValue)?)*
[98 (XQuery)]    DirAttributeValueXQ    ::=    ('"' (EscapeQuot | QuotAttrValueContent)* '"')
| ("'" (EscapeApos | AposAttrValueContent)* "'")
[99 (XQuery)]    QuotAttrValueContentXQ    ::=    QuotAttrContentChar
| CommonContent
[100 (XQuery)]    AposAttrValueContentXQ    ::=    AposAttrContentChar
| CommonContent
[149 (XQuery)]    QuotAttrContentCharXQ    ::=    Char - ["{}<&]
[150 (XQuery)]    AposAttrContentCharXQ    ::=    Char - ['{}<&]
[146 (XQuery)]    EscapeQuotXQ    ::=    '""'
[147 (XQuery)]    EscapeAposXQ    ::=    "''"
[29 (XQuery)]    EnclosedExprXQ    ::=    "{" Expr "}"

Core Grammar

The Core grammar productions for constructors are:

Constructors
[64 (Core)]    Constructor    ::=    ComputedConstructor
[65 (Core)]    ComputedConstructor    ::=    CompDocConstructor
| CompElemConstructor
| CompAttrConstructor
| CompTextConstructor
| CompCommentConstructor
| CompPIConstructor
[21 (Core)]    EnclosedExpr    ::=    "{" Expr "}"

There are no Core grammar productions for direct XML element or attribute constructors as they are normalized to computed constructors.

4.7.1 Direct Element Constructors

Introduction

The static and dynamic semantics of the direct forms of element and attribute constructors are specified on the equivalent computed element and attribute constructors.

Notation

The auxiliary mapping rules []ElementContent, []ElementContentUnit, []PartitionIntoUnits, and []DirCharsUnits are defined in this section and are used for the normalization of the content of direct element constructors.

Notation

An element-content unit is either a maximal contiguous sequence of literal characters (including character references, escaped braces, and predefined entity references), an enclosed expression, a direct element constructor, an XML comment, or an XML processing instruction. We use the following auxiliary grammar productions to describe element-content units.

[83 (Formal)]    ElementContentUnit    ::=    DirectConstructor | EnclosedExpr | DirCharsUnit
[84 (Formal)]    DirCharsUnit    ::=    (CDataSection | PredefinedEntityRef | CharRef | "{{" | "}}" | ElementContentChar)+

We use the auxiliary normalization rule [ DirElemContent* ]PartitionIntoUnits to restructure the original element content, DirElemContent*, into the appropriate sequence of element-content units. This normalization rule is not specified formally.

Here are three direct element constructors, each of which contains one element-content unit:

<date>{ xs:date("2003-03-18") }</date>

<name>Dizzy Gillespie</name>

<comment><!-- Just a comment --></comment>

The first contains one enclosed expression, the second contains one contiguous sequence of characters, and the third contains one XML comment.

After boundary whitespace is stripped, the next example contains six element-content units:

<address>
  <!-- Dizzy's address -->
  { 123 }-0A <street>Roosevelt Ave.</street> Flushing, NY { 11368 }
</address>

It contains an XML comment, followed by an enclosed expression that contains the integer 123, a contiguous sequence of characters ("-0A "), a direct XML element constructor, a contiguous sequence of characters (" Flushing, NY "), and an enclosed expression that contains the integer 11368. Evaluation of that constructor will result in the following element.

<address><!-- Dizzy's address -->123-0A <street>Roosevelt Ave.</street> Flushing, NY 11368</address>

Normalization

We start by giving the rules for the two forms of direct XML element constructors. Note that the direct attribute constructors are normalized twice: the []NamespaceAttrs normalizes the namespace-declaration attributes and []Attribute normalizes all other attributes that are not namespace-declaration attributes.

 
[ < QName DirAttributeList > DirElemContent* </ QName S? > ]Expr
==
element QName { [ DirAttributeList ]Attribute , [ [ DirElemContent* ]PartitionIntoUnits ]ElementContent } { [ DirAttributeList ]NamespaceAttrs }
 
[ < QName DirAttributeList /> ]Expr
==
element QName { [ DirAttributeList ]Attribute } { [ DirAttributeList ]NamespaceAttrs }

We can now give the rules for normalizing a direct element constructor's content. We distinguish between direct element constructors that contain only one element-content unit and those that contain more than one element-content unit.

Adjacent element-content units are convenient because they permit arbitrary interleaving of text and atomic data. During evaluation, atomic values are converted to text nodes containing the string representations of the atomic values, and then adjacent text nodes are concatenated together. In the example at the beginning of this section, the integer 123 is converted to a string and concatenated with "-0A" and the result is a single text node containing "123-0A".

Below are two examples of normalization for element constructors.

<date>{ xs:date("2003-03-18") }</date>
 =
element date { 
  fs:item-sequence-to-node-sequence(
    xs:date("2003-03-18")
  )
}

<address>
  <!-- Dizzy's address -->
  { 123 }-0A <street>Roosevelt Ave.</street> Flushing, NY { 11368 }
</address>
 =
element address {
  fs:item-sequence-to-node-sequence(
    comment { " Dizzy's address "},
    123, 
    text { "-0A "}, 
    element street {"Roosevelt Ave."},
    text { " Flushing, NY "  },
    11368
  )
}

We normalize each unit individually and construct a sequence of the normalized results interleaved with empty text nodes. The empty text nodes guarantee that the results of evaluating consecutive element-content units can be distinguished. Then we apply the function fs:item-sequence-to-node-sequence. Section 3.7.1 Direct Element ConstructorsXQ specifies the rules for converting a sequence of atomic values and nodes into a sequence of nodes before element construction. The Formal Semantics function fs:item-sequence-to-node-sequence implements these conversion rules.

 
[ElementContentUnit1]ElementContent
==
fs:item-sequence-to-node-sequence(([ ElementContentUnit1]ElementContentUnit))
 
[ElementContentUnit1, ..., ElementContentUnitn]ElementContent
==
fs:item-sequence-to-node-sequence(([ ElementContentUnit1 ]ElementContentUnit , text { "" }, ..., text { "" }, [ ElementContentUnitn]ElementContentUnit))

We must distinguish between the results of consecutive element-content units, because the rule for converting sequences of atomic values into strings applies to sequences within distinct enclosed expressions. The empty text nodes are eliminated during evaluation of fs:item-sequence-to-node-sequence when consecutive text nodes are coalesced into a single text node. The text node guarantees that a whitespace character will not be inserted between atomic values computed by distinct enclosed expressions. For example, here is an expression, its normalization, and the resulting XML value:

<example>{ 1 }{ 2 }</example>
 =
element example { fs:item-sequence-to-node-sequence ((1, text {""}, 2)) }
 ==>
<example>12</example>

In the absence of the empty text node, the expression would evaluate to the following incorrect value:

<example>{ 1 }{ 2 }</example>
 (incorrect normalization) =
element example { fs:item-sequence-to-node-sequence ((1, 2)) }
 (incorrect value) ==>
<example>1 2</example>

Next, we give the normalization rules for each element-content unit. The normalization rule for a contiguous sequence of characters assumes that the significant whitespace characters in element constructors have been preserved, as described in [4.7.1.4 Boundary Whitespace].

The following normalization rule takes the longest consecutive sequence of individual characters that include literal characters, escaped curly braces, character references, and predefined entity references and normalizes the character sequence as a text node containing the string of characters.

 
[DirCharsUnit]ElementContentUnit
==
text { [ DirCharsUnit ]DirCharsUnits }

The application of []DirCharsUnits to DirCharsUnit is defined informally. It produces a string literal corresponding to the content of the DirCharsUnit, in boundary whitespace is processed and non-literal characters (CharRefs, PredefinedEntityRefs, CDataSections, and escaped-braces) are resolved according to the rules in Section 3.7.1.3 ContentXQ.

XML processing instructions and comments in element content are normalized by applying the standard normalization rules for expressions, which appear in [4.7.2 Other Direct Constructors].

 
[DirPIConstructor]ElementContentUnit
==
[DirPIConstructor]Expr
 
[DirCommentConstructor]ElementContentUnit
==
[DirCommentConstructor]Expr

A direct element constructor is normalized using the normalization rule for expressions.

 
[DirElemConstructor]ElementContentUnit
==
[DirElemConstructor]Expr

An enclosed expression in element content is normalized by normalizing each individual expression in its expression sequence and then constructing a sequence of the normalized values:

 
[ { Expr1, ..., Exprn } ]ElementContentUnit
==
[ Expr1 ]Expr , ..., [ Exprn]Expr

Static Type Analysis

There are no additional static typing rules for direct XML element or attribute constructors.

Dynamic Evaluation

There are no additional dynamic evaluation rules for direct XML element or attribute constructors.

4.7.1.1 Attributes

Like direct element constructors, direct attribute constructors are normalized to computed attribute constructors.

Notation

The auxiliary mapping rules []Attribute, []AttributeContent, and []AttributeContentUnit, are defined in this section and are used for the normalization of direct attribute constructors.

We use the following grammar productions to represent AttributeContentUnits, i.e., the expressions used to compute the content of an attribute.

[87 (Formal)]    AttributeContentUnits    ::=    AttributeContentUnit*
[88 (Formal)]    AttributeContentUnit    ::=    EscapeQuot | QuotAttrValueContent

Normalization

Direct attributes may contain namespace-declaration attributes. The normalization rules in this section ignore namespace-declaration attributes -- they are handled by the normalization rules in [4.7.1.2 Namespace Declaration Attributes].

A DirAttributeList is normalized by the following rule, which maps each of the individual attribute-value expressions in the attribute list and constructs a sequence of the normalized values.

 
[
QName1 S? = S? DirAttributeValue1
...
QNamen S? = S? DirAttributeValuen
]Attribute
==
([QName1 S? = S? DirAttributeValue1 ]Attribute
...,
[QNamen S? = S? DirAttributeValuen]Attribute)

Namespace-declaration attributes, i.e., those attributes whose prefix is xmlns are ignored by mapping them to the empty sequence.

 
[Prefix:LocalPart S? = S? DirAttributeValue]Attribute
(Prefix = xmlns)
==
()

All attributes that are not namespace-declaration attributes are mapped to computed attribute constructors.

 
[Prefix:LocalPart S? = S? " AttributeContentUnits "]Attribute
not(Prefix = xmlns)
==
attribute Prefix:LocalPart { [AttributeContentUnits]AttributeContent}

As with literal XML elements, we need to distinguish between direct attribute constructors that contain one attribute-content unit and those that contain multiple attribute-content units, because the rule for converting sequences of atomic values into strings is applied to sequences within distinct enclosed expressions. If the direct attribute constructor contains exactly one attribute-content unit, we simply normalize that unit by applying the normalization rule for attribute content units:

 
[ AttributeContentUnit1 ]AttributeContent
==
[AttributeContentUnit1]AttributeContentUnit

If the direct attribute constructor contains more than one attribute-content unit, we normalize each unit individually and construct a sequence of the normalized results interleaved with empty text nodes. The empty text nodes guarantee that the results of evaluating consecutive attribute-content units can be distinguished. Then we apply the function fs:item-sequence-to-untypedAtomic, which applies the appropriate conversion rules to the normalized attribute content:

 
[ AttributeContentUnit1 ... AttributeContentUnitn ]AttributeContent
==
fs:item-sequence-to-untypedAtomic(([ AttributeContentUnit1 ]AttributeContentUnit , text { "" }, ..., text {""}, [ AttributeContentUnitn]AttributeContentUnit))

Literal characters, escaped curly braces, character references, and predefined entity references in attribute content are treated as in element content. In addition, the normalization rule for characters in attributes assumes:

  1. that an escaped single or double quote is converted to an individual single or double quote.

The following normalization rules take the longest consecutive sequence of individual characters that include literal characters, escaped curly braces, escaped quotes, character references, predefined entity references, and escaped single and double quotes and normalizes the character sequence as a string.

 
[( Char | CharRef | EscapeQuot | EscapeApos | PredefinedEntityRef ) +]AttributeContentUnit
==
fn:codepoints-to-string(( Char | CharRef | EscapeQuot | EscapeApos | PredefinedEntityRef )+)

We normalize an enclosed expression by normalizing each individual expression in its expression sequence and then constructing a sequence of the normalized values:

 
[ { Expr1, ..., Exprn } ]AttributeContentUnit
==
([ Expr1 ]Expr , ..., [ Exprn]Expr)
4.7.1.2 Namespace Declaration Attributes

Notation

The auxiliary mapping rules []NamespaceAttr, and []NamespaceAttrs are defined in this section and are used for the normalization of namespace declaration attributes.

Normalization

Some direct attributes may be namespace-declaration attributes. The normalization rules for namespace-declaration attributes ignore all non-namespace attributes -- they are handled by the normalization rules in [4.7.1.1 Attributes].

A DirAttributeList containing namespace-declaration attributes is normalized by the following rule, which maps each of the individual namespace-declaration attributes in the attribute list and constructs a sequence of the normalized namespace attribute values.

 
[
QName1 S? = S? DirAttributeValue1
...
QNamen S? = S? DirAttributeValuen
]NamespaceAttrs
==
([QName1 S? = S? DirAttributeValue1]NamespaceAttr
...,
[QNamen S? = S? DirAttributeValuen]NamespaceAttr)

Attributes whose prefix is not xmlns are ignored by mapping them to the empty sequence.

 
[Prefix:LocalPart S? = S? DirAttributeValue]NamespaceAttr
not(Prefix = xmlns)
==
()

Namespace-declaration attributes are normalized to local namespace declarations (NamespaceBinding). The content of such attributes must be defined with a URI literal.

 
[Prefix:LocalPart S? = S? " URILiteral "]NamespaceAttr
(Prefix = xmlns)
==
namespace LocalPart { URILiteral }
4.7.1.3 Content

The rules for normalizing element content are given above in [4.7.1 Direct Element Constructors].

4.7.1.4 Boundary Whitespace

Section 3.7.1.4 Boundary WhitespaceXQ describes how whitespace is processed in element constructors depending on the value of the boundary-space declaration in the query prolog. The Formal Semantics assumes that the rules for handling whitespace are applied by the (informally defined) auxiliary rule []DirCharsUnits.

4.7.2 Other Direct Constructors

Other Constructors
[105 (XQuery)]    DirPIConstructorXQ    ::=    "<?" PITarget (S DirPIContents)? "?>"
[106 (XQuery)]    DirPIContentsXQ    ::=    (Char* - (Char* '?>' Char*))
[103 (XQuery)]    DirCommentConstructorXQ    ::=    "<!--" DirCommentContents "-->"
[104 (XQuery)]    DirCommentContentsXQ    ::=    ((Char - '-') | ('-' (Char - '-')))*

Notation

The auxiliary mapping rule []Characters is defined in this section and used for the normalization of direct PI and comment constructors.

Normalization

A literal XML processing instruction is normalized into a computed processing-instruction constructor; its character content is converted to a string using the auxiliary mapping rule []Characters.

 
[<? NCName DirPIContents ?>]Expr
==
[processing-instruction NCName { [DirPIContents]Characters }]Expr

A literal XML comment is normalized into a computed comment constructor; its character content is converted to a string using the auxiliary mapping rule []Characters.

 
[<!-- DirCommentContents -->]Expr
==
[comment { [DirCommentContents]Characters }]Expr

The following normalization rule takes the character content of PI or comment constructors and creates a corresponding string.

 
[Char*]Characters
==
fn:codepoints-to-string(Char*)

Static Type Analysis

There are no additional static typing rules for direct processing-instruction or comment constructors.

Dynamic Evaluation

There are no additional dynamic evaluation rules for direct processing-instruction or comment constructors.

4.7.3 Computed Constructors

Computed Constructors
[109 (XQuery)]    ComputedConstructorXQ    ::=    CompDocConstructor
| CompElemConstructor
| CompAttrConstructor
| CompTextConstructor
| CompCommentConstructor
| CompPIConstructor
4.7.3.1 Computed Element Constructors

Introduction

This section describes the semantics of computed element constructors. Remember that direct element constructors are normalized into computed element constructors. This document does not formally specify how namespaces are copied. The semantics of namespaces copying in element constructors can be found in [XQuery 1.0: An XML Query Language].

[111 (XQuery)]    CompElemConstructorXQ    ::=    "element" (QName | ("{" Expr "}")) "{" ContentExpr? "}"
[112 (XQuery)]    ContentExprXQ    ::=    Expr

Core Grammar

The Core grammar productions for computed element constructors are:

Computed Element Constructors
[67 (Core)]    CompElemConstructor    ::=    "element" (QName | ("{" Expr "}")) "{" ContentExpr "}" "{" NamespaceBinding* "}"
[69 (Core)]    ContentExpr    ::=    Expr
[68 (Core)]    NamespaceBinding    ::=    "namespace" NCName "{" URILiteral "}"

Normalization

If the content expression is missing, the computed element constructor is normalized as if its content expression was the empty sequence.

 
[element QName { }]Expr
==
[element QName { () }]Expr

Computed element constructors are normalized using the fs:item-sequence-to-node-sequence function over their content expression.

 
[element QName { Expr }]Expr
==
element QName { fs:item-sequence-to-node-sequence(([Expr]Expr)) }

When the name of the element is also computed, the normalization rule applies atomization to the name expression.

 
[element { Expr1 } { Expr2 }]Expr
==
element { fn:data(([Expr1]Expr)) }{ fs:item-sequence-to-node-sequence(([Expr2]Expr)) }

Notation

The following auxiliary judgment adds a sequence of namespace bindings to the static context.

This judgment is defined as follows.

NamespaceBinding1 = namespace LocalPart1 { URILiteral1 }
...
NamespaceBindingn = namespace LocalPartn { URILiteraln }
dynEnvDefault |-  URILiteral1 has atomic value AnyURI
...
dynEnvDefault |-  URILiteral1 has atomic value AnyURI
statEnv1.namespace = statEnv0 + namespace(LocalPart1 => (passive, AnyURI1))
...
statEnvn.namespace = statEnvn-1 + namespace(LocalPartn => (passive, AnyURIn))

statEnv  |-  add namespace bindings NamespaceBinding1 ... NamespaceBindingn to statEnv0 yields statEnvn

Static Type Analysis

The normalization rules of direct element and attribute constructors leave us with only the computed forms of constructors. The static semantics for constructors is defined on all the computed forms. The computed element constructor itself has two forms: one in which the element name is a literal QName, and the other in which the element name is a computed expression.

A computed element constructor creates a new element with either the type annotationXQ xs:untyped (in strip construction mode), or with the type annotationXQ xs:anyType (in preserve construction mode). The content expression must return a sequence of nodes with all the attribute nodes before any element, processing-instructions or comment nodes. Note that the type allows text nodes interleaved with attribute nodes in the beginning. Although this results in a looser type checking, this accounts for the possible presence of empty text nodes resulting from normalization of direct element constructors (See [4.7.1 Direct Element Constructors]).

statEnv.constructionMode = preserve
add namespace bindings NamespaceBindings to statEnv1 yields statEnv2
statEnv2 |-  Expr : Type
statEnv2 |-  Type <: (attribute*, (element | comment | processing-instruction)*) & text*

statEnv1 |-  element QName { Expr } { NamespaceBindings } : element QName of type xs:anyType

statEnv.constructionMode = strip
add namespace bindings NamespaceBindings to statEnv1 yields statEnv2
statEnv2 |-  Expr : Type
statEnv2 |-  Type <: (attribute*, (element | comment | processing-instruction)*) & text*

statEnv1 |-  element QName { Expr } { NamespaceBindings } : element QName of type xs:untyped

In case the element name is computed as well, the name expression must be of type xs:QName, xs:string, or xs:untypedAtomic.

statEnv.constructionMode = preserve
add namespace bindings NamespaceBindings to statEnv1 yields statEnv2
statEnv2 |-  Expr1 : Type1
statEnv2 |-  Type1 <: (xs:QName | xs:string | xs:untypedAtomic)
statEnv2 |-  Expr2 : Type2
statEnv2 |-  Type2 <: (attribute*, (element | comment | processing-instruction)*) & text*

statEnv1 |-  element { Expr1 } { Expr2 } { NamespaceBindings } : element of type xs:anyType

statEnv.constructionMode = strip
add namespace bindings NamespaceBindings to statEnv1 yields statEnv2
statEnv2 |-  Expr1 : Type1
statEnv2 |-  Type1 <: (xs:QName | xs:string | xs:untypedAtomic)
statEnv2 |-  Expr2 : Type2
statEnv2 |-  Type2 <: (attribute*, (element | comment | processing-instruction)*) & text*

statEnv1 |-  element { Expr1 } { Expr2 } { NamespaceBindings } : element of type xs:untyped

Dynamic Evaluation

The following rules take a computed element constructor expression and construct an element node. The dynamic semantics for computed element constructors is the most complex of all expressions in XQuery. Here is how to read the rule below.

First, the element's content expression is partitioned into the local namespace declarations and all other expressions, and the local namespace declarations are evaluated, yielding a sequence of namespace bindings. The static environment is extended to include the new namespace bindings, which are all active. In Section 3.7.1.2 Namespace Declaration AttributesXQ, it is implementation-defined whether undeclaration of namespace prefixes (by setting the namespace prefix to the zero-length string) in an element constructor is supported. In the dynamic semantics below, we assume all local namespace declarations declare a binding of a prefix to a URI.

Second, the expression is evaluated, and the resulting value Value0 must match zero-or-more attributes followed by zero-or-more element, text, processing-instruction or comment nodes.

Third, the namespace bindings are concatenated with the list of active namespaces in the namespace environment statEnv.namespace and the namespaces corresponding to the element's name and all attributes names. The resulting sequence is the sequence of namespace bindings for the element.

Expr = Expr0
statEnvn; dynEnv |-  Expr0 => Value0
statEnv  |-  Value0 matches (attribute*, (element | text | processing-instruction | comment)*)

statEnv; dynEnv |-  element QName { Expr } => element QName of type xs:anyType { Value0 } { }

Expr = NamespaceBinding1, ..., NamespaceBindingn, Expr0
NamespaceBinding1 = namespace NCName1 { AnyURI1 }
...
NamespaceBindingn = namespace NCNamen { AnyURIn }
statEnv1 = statEnv + namespace(NCName1 => (active, AnyURI1))
...
statEnvn = statEnvn-1 + namespace(NCNamen => (active, AnyURIn))
statEnvn; dynEnv |-  Expr0 => Value0
statEnv  |-  Value0 matches (attribute*, (element | text | processing-instruction | comment)*)
NamespaceBindings = NamespaceBinding1, ..., NamespaceBindingn, fs:active_ns(statEnv), fs:get_static_ns_from_items(statEnv, Value0)

statEnv; dynEnv |-  element QName { Expr } => element QName of type xs:anyType { Value0 } { NamespaceBindings }

The dynamic evaluation of an element constructor with a computed name is similar. There is one additional rule that checks that the value of the element's name expression matches xs:QName.

dynEnv |- Expr1 => Value0
statEnv |-  Value0 matches xs:QName
QName = fn:prefix-from-QName(Value0):fn:local-name-from-QName(Value0)
dynEnv |-  element QName { Expr2 } => Value

dynEnv |-  element { Expr1 } { Expr2 } => Value

4.7.3.2 Computed Attribute Constructors
[113 (XQuery)]    CompAttrConstructorXQ    ::=    "attribute" (QName | ("{" Expr "}")) "{" Expr? "}"

Core Grammar

The Core grammar production for computed attribute constructors is:

Computed Attribute Constructors
[70 (Core)]    CompAttrConstructor    ::=    "attribute" (QName | ("{" Expr "}")) "{" Expr "}"

Normalization

Computed attribute constructors are normalized by mapping their name and content expression in a similar way as computed element constructors. The normalization rule uses the fs:item-sequence-to-untypedAtomic function.

 
[attribute QName { }]Expr
==
[attribute QName { () }]Expr
 
[attribute QName { Expr }]Expr
==
attribute QName { fs:item-sequence-to-untypedAtomic(([Expr]Expr)) }
 
[attribute { Expr1 } { Expr2 }]Expr
==
attribute { fn:data(([Expr1]Expr)) } { fs:item-sequence-to-untypedAtomic(([Expr2]Expr)) }

Static Type Analysis

The normalization rules for direct attribute constructors leave us with only the computed form of the attribute constructors. Like in a computed element constructor, a computed attribute constructor has two forms: one in which the attribute name is a literal QName, and the other in which the attribute name is a computed expression.

In the case of attribute constructors, the type annotationXQ is always xs:untypedAtomic.

statEnv |-  Expr : Type
statEnv  |-  Type <: xs:untypedAtomic

statEnv |-  attribute QName { Expr } : attribute QName of type xs:untypedAtomic

statEnv |-  Expr1 : Type1
statEnv |-  Type1 <: (xs:QName | xs:string | xs:untypedAtomic)
statEnv |-  Expr2 : Type2
statEnv |-  Type2 <: xs:untypedAtomic

statEnv |-  attribute { Expr1 } { Expr2 } : attribute of type xs:untypedAtomic

Dynamic Evaluation

The following rules take a computed attribute constructor expression and construct an attribute node. The rules are similar to those rules for element constructors. First, the attribute's name is expanded into a qualified name. Second, the function fs:item-sequence-to-untypedAtomic is applied to the content expression and this function call is evaluated in the dynamic environment. Recall from [4.7.3.2 Computed Attribute Constructors] that during normalization, we do not convert the content of direct attribute constructors that contain one attribute-content unit. This guarantees that useful type information is preserved for static analysis. Since the conversion function fs:item-sequence-to-untypedAtomic was not applied to all attribute constructors during normalization, we have to apply it at evaluation time. (As before, it is possible to elide the application of fs:item-sequence-to-untypedAtomic injected during normalization and the application injected during evaluation.)

dynEnv |-  fs:item-sequence-to-untypedAtomic(Expr) => AtomicValue

dynEnv |-  attribute QName { Expr } => attribute QName of type xs:untypedAtomic { AtomicValue }

dynEnv |-  Expr1 => Value1
statEnv |-  Value1 matches xs:QName
QName1 = fn:prefix-from-QName(Value1):fn:local-name-from-QName(Value1)
dynEnv |-  fs:item-sequence-to-untypedAtomic(Expr2) => AtomicValue2

dynEnv |-  attribute { Expr1 } { Expr2 } => attribute QName1 of type xs:untypedAtomic { AtomicValue2 }

4.7.3.3 Document Node Constructors
[110 (XQuery)]    CompDocConstructorXQ    ::=    "document" "{" Expr "}"

Core Grammar

The Core grammar production for a computed document constructor is:

Core computed document constructor
[66 (Core)]    CompDocConstructor    ::=    "document" "{" Expr "}"

Normalization

A document node constructor contains an expression, which must evaluate to a sequence of element, text, comment, or processing-instruction nodes. Section 3.7.3.3 Document Node ConstructorsXQ specifies the rules for converting a sequence of atomic values and nodes into a sequence of nodes before document construction. The built-in function [7.1.6 The fs:item-sequence-to-node-sequence-doc function] implements this conversion.

 
[document { Expr }]Expr
==
document { fs:item-sequence-to-node-sequence-doc(([Expr]Expr)) }

Static Type Analysis

The static typing rule does not need to check that the type of the argument expression is a sequence of element, text, processing-instruction, and comment nodes, as it is already checked by the fs:item-sequence-to-node-sequence-doc introduced during normalization. The type of the entire expression is the most general document type, because the document constructor erases all type annotationXQ on its content nodes.

statEnv |-  Expr : Type

statEnv |-  document { Expr } : document { Type }

Dynamic Evaluation

The dynamic semantics checks that the argument expression evaluates to a value that is a sequence of element, text, processing-instruction, or comment nodes. The entire expression evaluates to a new document node value. If the construction mode is set to strip, the type annotationXQ for all the nodes in content of a document node are erased.

statEnv.constructionMode = preserve
dynEnv |-  Expr => Value
statEnv |-  Value matches (element | text | processing-instruction | comment)*

dynEnv |-  document { Expr } => document { Value }

statEnv.constructionMode = strip
dynEnv |-  Expr => Value1
Value1 erases to Value2
statEnv |-  Value2 matches (element | text | processing-instruction | comment)*

dynEnv |-  document { Expr } => document { Value2 }

4.7.3.4 Text Node Constructors
[114 (XQuery)]    CompTextConstructorXQ    ::=    "text" "{" Expr "}"

Core Grammar

The Core grammar production for a computed text constructor is:

[71 (Core)]    CompTextConstructor    ::=    "text" "{" Expr "}"

Normalization

A text node constructor contains an expression, which must evaluate to an xs:string value. Section 3.7.3.4 Text Node ConstructorsXQ specifies the rules for converting a sequence of atomic values into a string prior to construction of a text node. Each node is replaced by its string value. For each adjacent sequence of one or more atomic values returned by an enclosed expression, a untyped atomic value is constructed, containing the canonical lexical representation of all the atomic values, with a single blank character inserted between adjacent values. As formal specification of these conversion rules is not instructive, [7.1.7 The fs:item-sequence-to-untypedAtomic function] implements this conversion.

 
[text { Expr }]Expr
==
text { (fs:item-sequence-to-untypedAtomic-text(fn:data(([Expr]Expr)))) cast as xs:string? }

Static Type Analysis

The static semantics checks that the argument expression has type xs:string or empty. The type of the entire expression is an optional text node type, as the text node constructor returns the empty sequence if its argument is the empty sequence.

statEnv |-  Expr : xs:string?

statEnv |-  text { Expr } : text?

Dynamic Evaluation

If the argument expression returns the empty sequence, the text node constructor returns the empty sequence.

dynEnv |-  Expr => ()

dynEnv |-  text { Expr } => ()

If the argument expression returns a value of type xs:string, the text node constructor returns a text node with that string as content.

dynEnv |-  Expr => Value      statEnv |-  Value matches xs:string

dynEnv |-  text { Expr } => text { Value }

4.7.3.5 Computed Processing Instruction Constructors
[116 (XQuery)]    CompPIConstructorXQ    ::=    "processing-instruction" (NCName | ("{" Expr "}")) "{" Expr? "}"

Core Grammar

The Core grammar production for computed processing-instruction constructors is:

[73 (Core)]    CompPIConstructor    ::=    "processing-instruction" (NCName | ("{" Expr "}")) "{" Expr? "}"

Normalization

Computed processing-instruction constructors are normalized by mapping their name and content expression in the same way that computed element and attribute constructors are normalized.

 
[processing-instruction NCName { }]Expr
==
[processing-instruction NCName { () }]Expr
 
[processing-instruction NCName { Expr }]Expr
==
processing-instruction NCName { fs:item-sequence-to-untypedAtomic-PI(([Expr]Expr)) }
 
[processing-instruction { Expr1 } { Expr2 }]Expr
==
processing-instruction { fn:data(([Expr1]Expr)) } { fs:item-sequence-to-untypedAtomic-PI(([Expr2]Expr)) }

Static Type Analysis

The static typing rules for processing-instruction constructors are straightforward.

statEnv |-  Expr : xs:untypedAtomic

statEnv |-  processing-instruction NCName { Expr } : processing-instruction

statEnv |-  Expr1 : (xs:NCName | xs:string | xs:untypedAtomic)      statEnv |-  Expr2 : xs:untypedAtomic

statEnv |-  processing-instruction { Expr1 } { Expr2 } : processing-instruction

Dynamic Evaluation

The dynamic evaluation rules for computed processing-instructions are straightforward.

dynEnv |-  Expr => Value      statEnv |-  Value matches xs:untypedAtomic

dynEnv |-  processing-instruction NCName { Expr } => processing-instruction NCName { Value }

dynEnv |-  Expr1 => Value1
statEnv |-  Value1 matches (xs:NCName | xs:untypedAtomic | xs:string)
xs:NCName(Value1) = NCName1
dynEnv |-  Expr2 => Value2      statEnv |-  Value2 matches xs:untypedAtomic

dynEnv |-  processing-instruction { Expr1 } { Expr2 } => processing-instruction NCName1 { Value2 }

4.7.3.6 Computed Comment Constructors
[115 (XQuery)]    CompCommentConstructorXQ    ::=    "comment" "{" Expr "}"

Core Grammar

The Core grammar production for computed comment constructors is:

[72 (Core)]    CompCommentConstructor    ::=    "comment" "{" Expr "}"

Normalization

Computed comment constructors are normalized by mapping their content expression.

 
[comment { Expr }]Expr
==
comment { (fs:item-sequence-to-untypedAtomic-comment(([Expr]Expr))) cast as xs:string }

Static Type Analysis

The static typing rule for computed comment constructors is straightforward.

statEnv |-  Expr : xs:string

statEnv |-  comment { Expr } : comment

Dynamic Evaluation

The dynamic evaluation rule for computed comment constructors is straightforward.

dynEnv |-  Expr => Value      statEnv |-  Value matches xs:string

dynEnv |-  comment { Expr } => comment { Value }

4.7.4 In-scope Namespaces of a Constructed Element

The effect of in-scope namespaces on constructed elements is specified in [4.7.1 Direct Element Constructors] and [4.7.3.1 Computed Element Constructors].

4.8 [For/FLWOR] Expressions

Introduction

[XPath/XQuery] provides [For/FLWOR] expressions for iteration, for binding variables to intermediate results, and filtering bound variables according to a predicate.

A FLWORExpr in XQuery 1.0 consists of a sequence of ForClauses and LetClauses, followed by an optional WhereClause, followed by an optional OrderByClause, as described by the following grammar productions. Each variable binding is preceded by an optional type declaration which specify the type expected for the variable.

The dynamic semantics of the ordering mode in FLWOR expressions is not specified formally, as it would require the introduction of tuples, which are not supported in the [XPath/XQuery] data model.

[For/FLWOR] Expressions
[33 (XQuery)]    FLWORExprXQ    ::=    (ForClause | LetClause)+ WhereClause? OrderByClause? "return" ExprSingle
[34 (XQuery)]    ForClauseXQ    ::=    "for" "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle ("," "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle)*
[36 (XQuery)]    LetClauseXQ    ::=    "let" "$" VarName TypeDeclaration? ":=" ExprSingle ("," "$" VarName TypeDeclaration? ":=" ExprSingle)*
[118 (XQuery)]    TypeDeclarationXQ    ::=    "as" SequenceType
[35 (XQuery)]    PositionalVarXQ    ::=    "at" "$" VarName
[37 (XQuery)]    WhereClauseXQ    ::=    "where" ExprSingle
[38 (XQuery)]    OrderByClauseXQ    ::=    (("order" "by") | ("stable" "order" "by")) OrderSpecList
[39 (XQuery)]    OrderSpecListXQ    ::=    OrderSpec ("," OrderSpec)*
[40 (XQuery)]    OrderSpecXQ    ::=    ExprSingle OrderModifier
[41 (XQuery)]    OrderModifierXQ    ::=    ("ascending" | "descending")? ("empty" ("greatest" | "least"))? ("collation" URILiteral)?
[4 (XPath)]    ForExprXP    ::=    SimpleForClause "return" ExprSingle
[5 (XPath)]    SimpleForClauseXP    ::=    "for" "$" VarName "in" ExprSingle ("," "$" VarName "in" ExprSingle)*

Core Grammar

The Core grammar productions for FLWOR expressions are:

For Expressions
[24 (Core)]    FLWORExpr    ::=    (ForClause | LetClause) "return" ExprSingle
[25 (Core)]    ForClause    ::=    "for" "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle
[27 (Core)]    LetClause    ::=    "let" "$" VarName TypeDeclaration? ":=" ExprSingle
[26 (Core)]    PositionalVar    ::=    "at" "$" VarName
[75 (Core)]    TypeDeclaration    ::=    "as" SequenceType
[28 (Core)]    OrderByClause    ::=    (("order" "by") | ("stable" "order" "by")) OrderSpecList
[29 (Core)]    OrderSpecList    ::=    OrderSpec ("," OrderSpec)*
[30 (Core)]    OrderSpec    ::=    ExprSingle OrderModifier
[31 (Core)]    OrderModifier    ::=    ("ascending" | "descending")? ("empty" ("greatest" | "least"))? ("collation" URILiteral)?

4.8.1 FLWOR expressions

Notation

For convenience, we introduce the following auxiliary grammar productions to represent optional type declarations and positional variables in For and Let clauses.

[79 (Formal)]    OptTypeDeclaration    ::=    TypeDeclaration?
[80 (Formal)]    OptPositionalVar    ::=    PositionalVar?

Notation

To facilitate the specification of normalization, we also introduce the following auxiliary grammar productions as an alternative grammar for FLWOR expressions.

[65 (Formal)]    FormalFLWORClause    ::=    ForClause | LetClause | WhereClause | OrderByClause
[66 (Formal)]    FormalReturnClause    ::=    FormalFLWORExpr | ("return" Expr)
[67 (Formal)]    FormalFLWORExpr    ::=    FormalFLWORClause FormalReturnClause

Normalization

Full FLWOR expressions are normalized to nested Core FLWOR expressions with a single for or let clause. Note that some of the normalization rules below accept ungrammatical FLWOR expressions such as "where Expr1 return Expr2". This does not matter, as normalization is always applied on parsed [XPath/XQuery] expressions, and such ungrammatical FLWOR expressions would be rejected by the parser beforehand.

Normalized FLWOR expressions restrict a For and Let clause to bind only one variable. Otherwise, the Core FLWOR expression is the same as the XQuery FLWOR expression. The first normalization rule is applied on a full [For/FLWOR] expression, splitting it at the clause level, then applying further normalization on each separate clause.

 
[
for $VarName1 OptTypeDeclaration1 OptPositionalVar1 in Expr1,
···,
$VarNamen OptTypeDeclarationn OptPositionalVarn in Exprn
[FormalReturnClause]Expr
] Expr
==
for $VarName1 OptTypeDeclaration1 OptPositionalVar1 in [Expr1]Expr return
  ···
     for $VarNamen OptTypeDeclarationn OptPositionalVarn in [ Exprn ]Expr
[FormalReturnClause]Expr

Likewise, a LetClause clause is normalized to nested let expressions, each of which binds one variable:

 
[
let $VarName1 OptTypeDeclaration1 := Expr1,
···,
$VarNamen OptTypeDeclarationn := Exprn
[FormalReturnClause]Expr
]Expr
==
let $VarName1 OptTypeDeclaration1 := [Expr1 ]Expr return
  ···
    let $VarNamen OptTypeDeclarationn := [Exprn]Expr return Expr
[FormalReturnClause]Expr

A WhereClause is normalized to an IfExpr, with the else-branch returning the empty sequence:

 
[ where Expr1 FormalReturnClause]Expr
==
if ( [Expr1]Expr ) then [FormalReturnClause]Expr else ()

The order by clause is normalized using the auxiliary mapping rule []OrderSpecList which is defined in [4.8.4 Order By and Return Clauses].

 
[ stable? order by OrderSpecList FormalReturnClause]Expr
==
[OrderSpecList]OrderSpecList return [FormalReturnClause]Expr

Finally, a stand-alone return clause is normalized into the corresponding expression. Recall that return keywords are introduced in the previous rule after the normalization of each clause.

 
[ return Expr ]Expr
==
[ Expr ]Expr

Example

The following simple example illustrates how a FLWORExpr is normalized. The for expression in the example below is used to iterate over two collections, binding variables $i and $j to items in these collections. It uses a let clause to bind the local variable $k to the sum of both numbers, and a where clause to select only those numbers that have a sum equal to or greater than the integer 5.

  for $i as xs:integer in (1, 2),
      $j in (3, 4)
  let $k := $i + $j
  where $k >= 5
  return
    <tuple>
       <i> { $i } </i>
       <j> { $j } </j>
    </tuple>

By the first set of rules, this is normalized to (except for the operators and element constructor which are not treated here):

  for $i as xs:integer in (1, 2) return
    for $j in (3, 4) return
      let $k := $i + $j return
        if ($k >= 5) then 
          <tuple>
            <i> { $i } </i>
            <j> { $j } </j>
          </tuple>
        else
          ()

For each binding of $i to an item in the sequence (1 , 2) the inner for expression iterates over the sequence (3 , 4) to produce tuples ordered by the ordering of the outer sequence and then by the ordering of the inner sequence. This Core expression eventually results in the following document fragment:

  (<tuple>
      <i>1</i>
      <j>4</j>
   </tuple>,
   <tuple>
      <i>2</i>
      <j>3</j>
   </tuple>,
   <tuple>
      <i>2</i>
      <j>4</j>
   </tuple>)

4.8.2 For expression

Static Type Analysis

A single for expression is typed as follows: First Type1 of the iteration expression Expr1 is inferred. Then the prime type of Type1, prime(Type1), is computed. This is a union over all item types in Type1 (See [8.4 Judgments for FLWOR and other expressions on sequences]). With the variable component of the static environment statEnv extended with $VarName1 as type prime(Type1), the type Type2 of Expr2 is inferred. Because the for expression iterates over the result of Expr1, the final type of the iteration is Type2 multiplied with the possible number of items in Type1 (one, ?, *, or +). This number is determined by the auxiliary type-function quantifier(Type1). Operations between quantifiers and types, such as Type2 · quantifier(Type1), used in the following rule, are defined in [8.4 Judgments for FLWOR and other expressions on sequences].

statEnv |-  Expr1 : Type1
statEnv |-  VarName1 of var expands to Variable1
statEnv + varType(Variable1 => prime(Type1))  |-  Expr2 : Type2

statEnv |-  for $VarName1 in Expr1 return Expr2 : Type2 · quantifier(Type1)

When a positional variable Variablepos is present, the static environment is also extended with the positional variable typed as an xs:integer.

statEnv |-  Expr1 : Type1
statEnv |-  VarName1 of var expands to Variable1
statEnv |-  VarNamepos of var expands to Variablepos
statEnv + varType(Variable1 => prime(Type1);Variablepos => xs:integer)  |-  Expr2 : Type2

statEnv |-  for $VarName1 at $VarNamepos in Expr1 return Expr2 : Type2 · quantifier(Type1)

When a type declaration is present, the static semantics also checks that the type of the input expression is a subtype of the declared type and extends the static environment by typing $VarName1 with type Type0. This semantics is specified by the following static typing rule.

statEnv |-  Expr1 : Type1
Type0 = [ SequenceType ]sequencetype
statEnv  |-  prime(Type1) <: Type0
statEnv |-  VarName1 of var expands to Variable1
statEnv + varType(Variable1 => Type0)  |-  Expr2 : Type2

statEnv |-  for $VarName1 as SequenceType in Expr1 return Expr2 : Type2 · quantifier(Type1)

The last rule handles For expressions that contain a type declaration and a positional variable. When the positional variable is present, the static environment is also extended with the positional variable typed as an integer.

statEnv |-  Expr1 : Type1
Type0 = [ SequenceType ]sequencetype
statEnv  |-  prime(Type1) <: Type0
statEnv |-  VarName1 of var expands to Variable1
statEnv |-  VarNamepos of var expands to Variablepos
statEnv + varType(Variable1 => Type0; Variablepos => xs:integer)  |-  Expr2 : Type2

statEnv |-  for $VarName1 as SequenceType at $VarNamepos in Expr1 return Expr2 : Type2 · quantifier(Type1)

Example

For example, if $example is bound to the sequence 10.0, 1.0E1, 10 of type xs:decimal, xs:float, xs:integer, then the query

  for $s in $example
  return $s * 2

is typed as follows:

  (1) prime(xs:decimal, xs:float, xs:integer) =
      xs:decimal | xs:float | xs:integer
  (2) quantifier(xs:decimal, xs:float, xs:integer) = +
  (3) $s : xs:decimal | xs:float | xs:integer
  (4) $s * 2 : 
      xs:decimal | xs:float | xs:integer
  (5) result-type :
      ( xs:decimal | xs:float | xs:integer ) +

This result-type is not the most specific type possible. It does not take into account the order of elements in the input type, and it ignores the individual and overall number of elements in the input type. The most specific type possible is: xs:decimal, xs:float, xs:integer. However, inferring such a specific type for arbitrary input types and arbitrary return clauses requires significantly more complex static typing rules. In addition, if put into the context of an element, the specific type violates the "unique particle attribution" restriction of XML schema, which requires that an element must have a unique content model within a particular context.

Dynamic Evaluation

The evaluation of a for expression distinguishes two cases: If the iteration expression Expr1 evaluates to the empty sequence, then the entire expression evaluates to the empty sequence:

dynEnv |-  Expr1 => ()

dynEnv |-  for $VarName1 OptTypeDeclaration OptPositionalVar in Expr1 return Expr2 => ()

Otherwise, the iteration expression Expr1 is evaluated to produce the sequence Item1, ..., Itemn. For each item Itemi in this sequence, the body of the for expression Expr2 is evaluated in the dynamic environment dynEnv extended with $VarName1 bound to Itemi. This produces values Valuei, ..., Valuen which are concatenated to produce the result sequence.

dynEnv |-  Expr1 => Item1 ,..., Itemn
statEnv  |-  VarName of var expands to Variable
dynEnv + varValue(Variable => Item1)  |-  Expr2 => Value1
···
dynEnv + varValue(Variable => Itemn)  |-  Expr2 => Valuen

dynEnv |-  for $VarName in Expr1 return Expr2 => Value1 ,..., Valuen

The following rule is the same as the rule above, but includes the optional positional variable $VarNamepos. If present, $VarNamepos is bound to the position of the item in the input sequence, i.e., the value i.

dynEnv |-  Expr1 => Item1 ,..., Itemn
statEnv  |-  VarName of var expands to Variable      statEnv  |-  VarNamepos of var expands to Variablepos
dynEnv + varValue(Variable => Item1; Variablepos => 1)  |-  Expr2 => Value1
···
dynEnv + varValue(Variable => Itemn; Variablepos => n)  |-  Expr2 => Valuen

dynEnv |-  for $VarName at $VarNamepos in Expr1 return Expr2 => Value1 ,..., Valuen

When a type declaration is present, the dynamic semantics also checks that each item in the result of evaluating Expr1 matches the declared type. This semantics is specified by the following dynamic evaluation rule.

dynEnv |-  Expr1 => Item1 ,..., Itemn
Type0 = [ SequenceType ]sequencetype
statEnv  |-  VarName of var expands to Variable
dynEnv + varValue(Variable => Item1)  |-  Expr2 => Value1
statEnv  |-  Item1 matches Type0
···
statEnv  |-  Itemn matches Type0
dynEnv + varValue(Variable => Itemn)  |-  Expr2 => Valuen

dynEnv |-  for $VarName as SequenceType in Expr1 return Expr2 => Value1 ,..., Valuen

The last rule covers a for expression that contains a type declaration and a positional variable.

dynEnv |-  Expr1 => Item1 ,..., Itemn
Type0 = [ SequenceType ]sequencetype
statEnv  |-  VarName of var expands to Variable
statEnv  |-  VarNamepos of var expands to Variablepos
dynEnv + varValue(Variable => Item1; Variablepos => 1)  |-  Expr2 => Value1
statEnv  |-  Item1 matches Type0
···
statEnv  |-  Itemn matches Type0
dynEnv + varValue(Variable => Itemn; Variablepos => n)  |-  Expr2 => Valuen

dynEnv |-  for $VarName as SequenceType at $VarNamepos in Expr1 return Expr2 => Value1 ,..., Valuen

Note that this definition allows non-deterministic evaluation of the resulting sequence, since the preconditions in the above rule can be evaluated in any order.

Example

Note that if the expression in the return clause results in a sequence, sequences are never nested in the [XPath/XQuery] data model. For instance, in the following for expression:

  
  for $i in (1,2)
    return (<i> {$i} </i>, <negi> {-$i} </negi>)

each iteration in the for results in a sequence of two elements, which are then concatenated and flattened in the resulting sequence:

  
  (<i>1</i>,
   <negi>-1</negi>,
   <i>2</i>,
   <negi>-2</negi>)

4.8.3 Let Expression

Static Type Analysis

A let expression extends the static environment statEnv with Variable1 of type Type1 inferred from Expr1, and infers the type of Expr2 in the extended environment to produce the result type Type2.

statEnv |-  Expr1 : Type1      statEnv  |-  VarName of var expands to Variable      statEnv + varType(Variable => Type1)  |-  Expr2 : Type2

statEnv |-  let $VarName := Expr1 return Expr2 : Type2

When a type declaration is present, the static semantics also checks that the type of the input expression is a subtype of the declared type and extends the static environment by typing Variable1 with type Type0. This semantics is specified by the following static typing rule.

statEnv |-  Expr1 : Type1
Type0 = [ SequenceType ]sequencetype
statEnv  |-  Type1 <: Type0
statEnv  |-  VarName of var expands to Variable      statEnv + varType(Variable1 => Type0 )  |-  Expr2 : Type2

statEnv |-  let $VarName1 as SequenceType := Expr1 return Expr2 : Type2

Dynamic Evaluation

A let expression extends the dynamic environment dynEnv with Variable bound to Value1 returned by Expr1, and evaluates Expr2 in the extended environment to produce Value2.

dynEnv |-  Expr1 => Value1
statEnv  |-  VarName of var expands to Variable      dynEnv + varValue(Variable1 => Value1)  |-  Expr2 => Value2

dynEnv |-  let $VarName1 := Expr1 return Expr2 => Value2

When a type declaration is present, the dynamic semantics also checks that the result of evaluating Expr1 matches the declared type. This semantics is specified as the following dynamic evaluation rule.

dynEnv |-  Expr1 => Value1
Type0 = [ SequenceType ]sequencetype
statEnv  |-  Value1 matches Type0
statEnv  |-  VarName of var expands to Variable      dynEnv + varValue(Variable1 => Value1)  |-  Expr2 => Value2

dynEnv |-  let $VarName1 as SequenceType := Expr1 return Expr2 => Value2

Example

Note the use of the environments to define the scope of each variable. For instance, in the following nested let expression:

  let $k := 5 return
    let $k := $k + 1 return
      $k+1

the outermost let expression binds variable $k to the integer 5 in the environment, then the expression $k+1 is computed, yielding value 6, to which the second variable $k is bound. The expression then results in the final integer 7.

4.8.4 Order By and Return Clauses

Introduction

The dynamic semantics of the OrderByClause is not specified formally, as doing so would require the introduction of tuples, which are not supported in the [XPath/XQuery] data model. The dynamic semantics of the order-by clause can be found in Section 3.8.3 Order By and Return ClausesXQ.

Because an OrderByClause does not affect the type of a FLWORExpr expression, the static semantics of a FLWORExpr expression with an OrderByClause is equivalent to the static semantics of an equivalent FLWORExpr in which the OrderByClause is replaced by a call to the gt comparison over the corresponding OrderSpec expression(s).

Notation

To define normalization of OrderBy, the following auxiliary mapping rule is used.

 
[OrderSpecList]OrderSpecList
==
LetClause ... LetClause

This rules specifies that OrderSpecList is mapped to a sequence of LetClauses.

Normalization

Proper static typing for FLWOR expressions with an OrderByClause is obtained by normalizing the OrderByClause to a Let clause, nested For expressions, and atomization, then by applying the standard static typing rules for those expressions. Note that if evaluated dynamically, the normalization of OrderByClause given here does not express the required sorting semantics. Notably, the normalization rule introduces the gt operation which is used implicitely in the semantics of order by.

Each OrderSpec is normalized by the following rules.

 
[OrderSpec1 ... OrderSpecn]OrderSpecList
==
[OrderSpec1]OrderSpecList, ... [OrderSpecn]OrderSpecList
 
[Expr OrderModifier]OrderSpecList
==
let $fs:new0 :=
   let $fs:new1 := [Expr]
   for $fs:new2 in $fs:new1 return
   for $fs:new3 in $fs:new1 return
     [$fs:new2 gt $fs:new3]Expr
[OrderSpecList]OrderSpecList

4.9 Ordered and Unordered Expressions

Introduction

The purpose of ordered and unordered expressions is to set the ordering mode in the static context to ordered or unordered for a certain region in a query. The specified ordering mode applies to the expression nested inside the curly braces.

[91 (XQuery)]    OrderedExprXQ    ::=    "ordered" "{" Expr "}"
[92 (XQuery)]    UnorderedExprXQ    ::=    "unordered" "{" Expr "}"

Core Grammar

The Core grammar productions for ordered/unordered expressions are:

[61 (Core)]    OrderedExpr    ::=    "ordered" "{" Expr "}"
[62 (Core)]    UnorderedExpr    ::=    "unordered" "{" Expr "}"

Normalization

OrderedExpr (resp. UnorderedExpr) expressions are normalized to OrderedExpr (resp. UnorderedExpr) expressions in the [XPath/XQuery] Core.

 
[ordered { Expr }]Expr
==
ordered { [Expr]Expr }
 
[unordered { Expr }]Expr
==
unordered { [Expr]Expr }

Static Type Analysis

OrderedExpr and UnorderedExpr expressions set the ordering mode in the static context to ordered or unordered.

statEnv1 = statEnv + orderingMode(ordered)
statEnv1 |-  Expr : Type

statEnv |-  ordered { Expr } : Type

statEnv1 = statEnv + orderingMode(unordered)
statEnv1 |-  Expr : Type

statEnv |-  unordered { Expr } : Type

Dynamic Evaluation

OrderedExpr and UnorderedExpr expressions only have an effect on the static context. The effect on the evaluation of its subexpression(s) is captured using the fs:apply-ordering-mode function, which introduced during normalization of axis steps, union, intersect, and except expressions, and FLWOR expressions that have no order by clause.

dynEnv |-  Expr => Value

dynEnv |-  ordered { Expr } => Value

dynEnv |-  Expr => Value

dynEnv |-  unordered { Expr } => Value

4.10 Conditional Expressions

Introduction

A conditional expression supports conditional evaluation of one of two expressions.

Conditional Expression
[45 (XQuery)]    IfExprXQ    ::=    "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle

Core Grammar

The Core grammar production for the conditional expression is:

Core Conditional Expression
[35 (Core)]    IfExpr    ::=    "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle

Normalization

Conditional expressions are normalized as follows.

 
[if (Expr1) then Expr2 else Expr3]Expr
==
  if (fn:boolean(([ Expr1 ]Expr))) then [Expr2]Expr else [Expr3]Expr

Static Type Analysis

statEnv |-  Expr1 : xs:boolean      statEnv |-  Expr2 : Type2      statEnv |-  Expr3 : Type3

statEnv |-  if (Expr1) then Expr2 else Expr3 : (Type2 | Type3)

Dynamic Evaluation

If the conditional's boolean expression Expr1 evaluates to true, Expr2 is evaluated and its value is produced. If the conditional's boolean expression evaluates to false, Expr3 is evaluated and its value is produced. Note that the existence of two separate dynamic evaluation rules ensures that only one branch of the conditional is evaluated.

dynEnv |-  Expr1 => true      dynEnv |-  Expr2 => Value2

dynEnv |-  if (Expr1) then Expr2 else Expr3 => Value2

dynEnv |-  Expr1 => false      dynEnv |-  Expr3 => Value3

dynEnv |-  if (Expr1) then Expr2 else Expr3 => Value3

4.11 Quantified Expressions

Introduction

[XPath/XQuery] defines two quantification expressions:

Quantified Expression
[42 (XQuery)]    QuantifiedExprXQ    ::=    ("some" | "every") "$" VarName TypeDeclaration? "in" ExprSingle ("," "$" VarName TypeDeclaration? "in" ExprSingle)* "satisfies" ExprSingle
[6 (XPath)]    QuantifiedExprXP    ::=    ("some" | "every") "$" VarName "in" ExprSingle ("," "$" VarName "in" ExprSingle)* "satisfies" ExprSingle

Core Grammar

The Core grammar production for quantified expressions is:

[32 (Core)]    QuantifiedExpr    ::=    ("some" | "every") "$" VarName TypeDeclaration? "in" ExprSingle ("," "$" VarName TypeDeclaration? "in" ExprSingle)* "satisfies" ExprSingle

Normalization

The quantified expressions are normalized into nested Core quantified expressions, each of which binds one variable.

 
[some $VarName1 in Expr1, ..., $VarNamen in Exprn satisfies Expr]Expr
==
some $VarName1 in [Expr1]Expr satisfies
   some $VarName2 in [Expr2]Expr satisfies
         ...
     some $VarNamen in [Exprn]Expr satisfies
     fn:boolean(([Expr]Expr))
 
[every $VarName1 in Expr1, ..., $VarNamen in Exprn satisfies Expr]Expr
==
every $VarName1 in [Expr1]Expr satisfies
   every $VarName2 in [Expr2]Expr satisfies
         ...
     every $VarNamen in [Exprn]Expr satisfies
     fn:boolean(([Expr]Expr))

Static Type Analysis

The static semantics of the quantified expressions uses the notion of prime type. These rules are similar to those for for expressions in [4.8.2 For expression].

statEnv |-  Expr1 : Type1
statEnv  |-  VarName1 of var expands to Variable1
statEnv + varType(Variable1 => prime(Type1))  |-  Expr2 : xs:boolean

statEnv |-  some $VarName1 in Expr1 satisfies Expr2 : xs:boolean

The next rule is for SomeExpr with the optional type declaration.

statEnv |-  Expr1 : Type1
Type0 = [ SequenceType ]sequencetype
statEnv  |-  prime(Type1) <: Type0
statEnv  |-  VarName1 of var expands to Variable1
statEnv + varType(Variable1 => Type0)  |-  Expr2 : xs:boolean

statEnv |-  some $VarName1 as SequenceType in Expr1 satisfies Expr2 : xs:boolean

The next rule is for EveryExpr without the optional type declaration.

statEnv |-  Expr1 : Type1
statEnv  |-  VarName1 of var expands to Variable1
statEnv + varType(Variable1 => prime(Type1))  |-  Expr2 : xs:boolean

statEnv |-  every $VarName1 in Expr1 satisfies Expr2 : xs:boolean

The next rule is for EveryExpr with the optional type declaration.

statEnv |-  Expr1 : Type1
Type0 = [ SequenceType ]sequencetype
statEnv  |-  prime(Type1) <: Type0
statEnv  |-  VarName1 of var expands to Variable1
statEnv + varType(Variable1 => Type0)  |-  Expr2 : xs:boolean

statEnv |-  every $VarName1 as SequenceType in Expr1 satisfies Expr2 : xs:boolean

Dynamic Evaluation

If its input expression returns the empty sequence, the SomeExpr expression returns false.

dynEnv |-  Expr1 => ()

dynEnv |-  some $VarName1 OptTypeDeclaration in Expr1 satisfies Expr2 => false

The SomeExpr expression yields true if any evaluation of the satisfies expression yields true. The SomeExpr expression yields false if every evaluation of the satisfies expression is false. A quantified expression may raise an error if any evaluation of the satisfies expression raises an error. The dynamic semantics of quantified expressions is non-deterministic. This non-determinism permits implementations to use short-circuit evaluation strategies when evaluating quantified expressions.

dynEnv |-  Expr1 => Item1, ..., Itemn
statEnv  |-  VarName1 of var expands to Variable1
dynEnv + varValue(Variable1 => Itemi)  |-  Expr2 => true
i in { 1,...,n }

dynEnv |-  some $VarName1 in Expr1 satisfies Expr2 => true

The next rule is for SomeExpr with the optional type declaration, in which some evaluation of the satisfies expression yields true.

dynEnv |-  Expr1 => Item1, ..., Itemn
Type0 = [ SequenceType ]sequencetype
statEnv  |-  Itemi matches Type0
i in { 1,...,n }
statEnv  |-  VarName1 of var expands to Variable1
dynEnv + varValue(Variable1 => Itemi)  |-  Expr2 => true

dynEnv |-  some $VarName1 as SequenceType in Expr1 satisfies Expr2 => true

The next rule is for SomeExpr without the optional type declaration, in which all evaluations of the satisfies expression yield false.

dynEnv |-  Expr1 => Item1, ..., Itemn
statEnv  |-  VarName1 of var expands to Variable1
dynEnv + varValue(Variable1 => Item1)  |-  Expr2 => false
...
dynEnv + varValue(Variable1 => Itemn)  |-  Expr2 => false

dynEnv |-  some $VarName1 in Expr1 satisfies Expr2 => false

The next rule is for SomeExpr with the optional type declaration, in which all evaluations of the satisfies expression yield false.

dynEnv |-  Expr1 => Item1, ..., Itemn
Type0 = [ SequenceType ]sequencetype
statEnv  |-  VarName1 of var expands to Variable1
dynEnv + varValue(Variable1 => Item1)  |-  Expr2 => false
statEnv  |-  Item1 matches Type0
...
dynEnv + varValue(Variable1 => Itemn)  |-  Expr2 => false
statEnv  |-  Itemn matches Type0

dynEnv |-  some $VarName1 as SequenceType in Expr1 satisfies Expr2 => false

If its input expression returns the empty sequence, the EveryExpr expression returns true.

dynEnv |-  Expr1 => ()

dynEnv |-  every $VarName1 OptTypeDeclaration in Expr1 satisfies Expr2 => true

The EveryExpr expression yields false if any evaluation of the satisfies expression yields false. The EveryExpr expression yields true if every evaluation of the satisfies expression is true.

dynEnv |-  Expr1 => Item1, ..., Itemn
statEnv  |-  VarName1 of var expands to Variable1
dynEnv + varValue(Variable1 => Itemi)  |-  Expr2 => false
i in { 1,...,n }

dynEnv |-  every $VarName1 in Expr1 satisfies Expr2 => false

The next rule is for EveryExpr with the optional type declaration, in which some evaluation of the satisfies expression yields false.

dynEnv |-  Expr1 => Item1, ..., Itemn
Type0 = [ SequenceType ]sequencetype
statEnv  |-  Itemi matches Type0
statEnv  |-  VarName1 of var expands to Variable1
dynEnv + varValue(Variable1 => Itemi)  |-  Expr2 => false
i in { 1,...,n }

dynEnv |-  every $VarName1 as SequenceType in Expr1 satisfies Expr2 => false

The next rule is for EveryExpr in which all evaluations of the satisfies expression yield true.

dynEnv |-  Expr1 => Item1, ..., Itemn
statEnv  |-  VarName1 of var expands to Variable1
dynEnv + varValue(Variable1 => Item1)  |-  Expr2 => true
...
dynEnv + varValue(Variable1 => Itemn)  |-  Expr2 => true

dynEnv |-  every $VarName1 in Expr1 satisfies Expr2 => true

The next rule is for EveryExpr with the optional type declaration in which all evaluations of the satisfies expression yield true.

dynEnv |-  Expr1 => Item1, ..., Itemn
Type0 = [ SequenceType ]sequencetype
statEnv  |-  VarName1 of var expands to Variable1
dynEnv + varValue(Variable1 => Item1)  |-  Expr2 => true
statEnv  |-  Item1 matches Type0
...
dynEnv + varValue(Variable1 => Itemn)  |-  Expr2 => true
statEnv  |-  Itemn matches Type0

dynEnv |-  every $VarName1 as SequenceType in Expr1 satisfies Expr2 => true

4.12 Expressions on SequenceTypes

Introduction

Some of the expressions relying on the SequenceTypes syntax are called expressions on SequenceTypes. The syntax of SequenceTypes is described in [3.5.3 SequenceType Syntax].

4.12.1 Instance Of

SequenceType expressions
[54 (XQuery)]    InstanceofExprXQ    ::=    TreatExpr ( "instance" "of" SequenceType )?

Introduction

The SequenceType expression "Expr instance of SequenceType" is true if and only if the result of evaluating expression Expr is an instance of the type referred to by SequenceType.

Normalization

An InstanceofExpr expression is normalized into a TypeswitchExpr expression. Note that the following normalization rule uses a variable $fs:new, which is a newly created variable which must not conflict with any variables already in scope. This variable is necessary to comply with the syntax of typeswitch expressions in the Core [XPath/XQuery], but is never used.

 
[Expr instance of SequenceType]Expr
==
typeswitch ([ Expr ]Expr)
  case $fs:new as SequenceType return fn:true()
  default $fs:new return fn:false()

4.12.2 Typeswitch

SequenceType expressions
[43 (XQuery)]    TypeswitchExprXQ    ::=    "typeswitch" "(" Expr ")" CaseClause+ "default" ("$" VarName)? "return" ExprSingle
[44 (XQuery)]    CaseClauseXQ    ::=    "case" ("$" VarName "as")? SequenceType "return" ExprSingle

Introduction

The typeswitch expression chooses one of several expressions to evaluate based on the dynamic type of an input value.

Each branch of a typeswitch expression may have an optional $VarName, which is bound to the value of the input expression. One reason for using a variable on one of the branches is that it is assigned a type specific for that branch. This variable is optional in [XPath/XQuery] but made mandatory in the [XPath/XQuery] Core.

Core Grammar

The Core grammar productions for typeswitch are:

[33 (Core)]    TypeswitchExpr    ::=    "typeswitch" "(" Expr ")" CaseClause+ "default" "$" VarName "return" ExprSingle
[34 (Core)]    CaseClause    ::=    "case" "$" VarName "as" SequenceType "return" ExprSingle

Notation

For convenience, we introduce the following auxiliary grammar production.

[81 (Formal)]    OptVarName    ::=    ("$" VarName)?

Notation

To define normalization of case clauses to the [XPath/XQuery] Core, the following auxiliary mapping rules are used.

 
[CaseClause]Case
==
CaseClause

specifies that CaseClause is mapped to CaseClause, in the [XPath/XQuery] Core.

Normalization

Normalization of a typeswitch expression guarantees that every branch has an associated $VarName. The following normalization rules add newly created variables that must not conflict with any variables already in scope and that are not used in any of the sub-expressions.

 
[   case SequenceType return Expr ]Case
==
  case $fs:new1 as SequenceType return [ Expr ]Expr
 
[   case $VarName as SequenceType return Expr ]Case
==
  case $VarName as SequenceType return [ Expr ]Expr
 
[ default return Expr ]Case
==
default $fs:new1 return [ Expr ]Expr
 
[ default $VarName return Expr ]Case
==
default $VarName return [ Expr ]Expr
 
[
typeswitch ( Expr0 )
  CaseClause1
    ···
  CaseClausen
  default OptVarName return Exprn+1
]Expr
==
typeswitch ( [ Expr0 ]Expr )
[CaseClause1]Case
    ···
[CaseClausen]Case
[  default OptVarName return Exprn+1 ]Case

Notation

For convenience, we use the following auxiliary grammar productions to denote case clauses in a typeswitch.

FormalCaseClauses
[68 (Formal)]    FormalCaseClauses    ::=    (FormalCaseClause FormalCaseClauses) | FormalDefaultCaseClause
[69 (Formal)]    FormalCaseClause    ::=    "case" "$" VarName "as" SequenceType "return" Expr
[70 (Formal)]    FormalDefaultCaseClause    ::=    "default" "$" VarName "return" Expr

The following judgments

statEnv |-  Type1 case FormalCaseClause : Type
statEnv |-  Type1 case FormalDefaultCaseClause : Type

is used in the static semantics of typeswitch. It indicates that under the static environment statEnv, and with the input type of the typeswitch being Type1, the given case clause yields the type Type.

The following judgment

dynEnv |-  Value1 against FormalCaseClauses => Value2

is used in the dynamic semantics of typeswitch. It indicates that under the dynamic environment dynEnv, with the input value of the typeswitch being Value1, the given case clauses yield the value Value2.

Static Type Analysis

The static typing rules for the typeswitch expression are simple. Each case clause and the default clause of the typeswitch is typed independently. The type of the entire typeswitch expression is the union of the types of all the clauses.

statEnv |-  Expr0 : Type0
statEnv |-  Type0 case case $VarName1 as SequenceType1 return Expr1 : Type1
    ···
statEnv |-  Type0 case case $VarNamen as SequenceTypen return Exprn : Typen
statEnv |-  Type0 case default $VarNamen+1 return Exprn : Typen+1

statEnv |- 
statEnv |-  
(typeswitch (Expr0)
  case $VarName1 as SequenceType1 return Expr1
    ···
  case $VarNamen as SequenceTypen return Exprn
  default $VarNamen+1 return Exprn+1)
: (Type1 | ... | Typen+1)

To type one case clause, the case variable is assigned the type of the case clause CaseType and the body of the clause is typed in the extended environment. Thus, the type of a case clause is independent of the type of the input expression.

CaseType = [ SequenceType ]sequencetype
statEnv |-  VarName of var expands to Variable
statEnv + varType(Variable => CaseType )  |-  Expr : Type

statEnv |-  Type0 case case $VarName as SequenceType return Expr : Type

To type the default clause, the variable is assigned the type of the input expression and the body of the default clause is typed in the extended environment.

statEnv |-  VarName of var expands to Variable
statEnv + varType(Variable => Type0 )  |-  Expr : Type

statEnv |-  Type0 case default $VarName return Expr : Type

Dynamic Evaluation

The evaluation of a typeswitch proceeds as follows. First, the input expression is evaluated, yielding an input value. The effective case is the first case clause such that the input value matches the SequenceType in the case clause. The return clause of the effective case is evaluated and the value of the return expression is the value of the typeswitch expression.

dynEnv |-  Expr => Value0
dynEnv |-  Value0 against FormalCaseClauses => Value1

dynEnv |-  typeswitch (Expr) FormalCaseClauses => Value1

If the value matches the sequence type, the following rule applies: It extends the dynamic environment by binding the variable Variable to Value0 and evaluates the body of the return clause.

CaseType = [ SequenceType ]sequencetype
statEnv  |-  Value0 matches CaseType
statEnv  |-  VarName of var expands to Variable
dynEnv + varValue(Variable => Value0)  |-  Expr => Value1

dynEnv |-  Value0 against case $VarName as SequenceType return Expr FormalCaseClauses => Value1

If the value does not match the sequence type, the current case is not evaluated, and the remaining case rules are evaluated in order by applying the inference rule recursively.

CaseType = [ SequenceType ]sequencetype      statEnv  |-  not(Value0 matches CaseType)      dynEnv |-  Value0 against FormalCaseClauses => Value1

dynEnv |-  Value0 against case $VarName as SequenceType return Expr FormalCaseClauses => Value1

The last rule states that the default branch of a typeswitch expression always evaluates to the value of its return clause.

statEnv  |-  VarName of var expands to Variable
dynEnv + varValue(Variable => Value0)  |-  Expr => Value1

dynEnv |-  Value0 against default $VarName return Expr => Value1

4.12.3 Cast

Introduction

The cast expression can be used to convert a value to a specific datatype. It changes both the type and value of the result of an expression, and can only be applied to an atomic value.

[57 (XQuery)]    CastExprXQ    ::=    UnaryExpr ( "cast" "as" SingleType )?
[117 (XQuery)]    SingleTypeXQ    ::=    AtomicType "?"?

Core Grammar

The Core grammar productions for cast expressions are:

[39 (Core)]    CastExpr    ::=    ValueExpr ( "cast" "as" SingleType )?
[74 (Core)]    SingleType    ::=    AtomicType "?"?

Normalization

The normalization of cast applies atomization to its argument. The type declaration asserts that the result is a single atomic value. The second normalization rule applies when the target type is optional.

 
[Expr cast as AtomicType ]Expr
==
let $v as xs:anyAtomicType := fn:data(([ Expr ]Expr)) return
  $v cast as AtomicType
 
[Expr cast as AtomicType? ]Expr
==
let $v as xs:anyAtomicType? := fn:data(([ Expr ]Expr)) return
  typeswitch ($v)
    case $fs:new as empty-sequence() return ()
    default $fs:new return $v cast as AtomicType

Static Type Analysis

The static typing rule of cast expression is as follows. The type of a Core cast expression is always the target type. Note that a cast expression can fail at run-time if the given value cannot be cast to the target type.


statEnv |-  Expr cast as AtomicType : AtomicType

Notation

The dynamic semantics of cast expressions is defined in Section 17 CastingFO. The semantics of cast expressions depends on the type of the input value and on the target type. For any source and target primitive types, the casting table in Section 17 CastingFO indicates whether the cast from the source type to the target type is permitted. When a cast is permitted, the detailed dynamic evaluation rules for cast in Section 17 CastingFO are applied. We refer to those rules using an auxiliary judgment defined as follows.

The judgment

AtomicValue1 cast value to type AtomicType => AtomicValue2

holds if AtomicValue1 can be cast to type AtomicType, resulting in the new value AtomicValue2 according to the rules in Section 17 CastingFO.

Dynamic Evaluation

dynEnv |-  Expr => AtomicValue1
AtomicValue1 cast value to type AtomicType => AtomicValue2

dynEnv |-  Expr cast as AtomicType => AtomicValue2

4.12.4 Castable

[56 (XQuery)]    CastableExprXQ    ::=    CastExpr ( "castable" "as" SingleType )?

Castable expressions check whether a value can be cast to a given type.

Core Grammar

The Core grammar production for castable is:

[38 (Core)]    CastableExpr    ::=    CastExpr ( "castable" "as" SingleType )?

Normalization

The normalization of castable simply maps its expression argument.

 
[Expr castable as AtomicType]Expr
==
let $v as xs:anyAtomicType := fn:data(([ Expr ]Expr)) return
$v castable as AtomicType
 
[Expr castable as AtomicType?]Expr
==
let $v as xs:anyAtomicType? := fn:data(([ Expr ]Expr)) return
$v castable as AtomicType?

Static Type Analysis

The type of a Core castable expression is always a boolean.


statEnv |-  Expr castable as AtomicType : xs:boolean

Dynamic Evaluation

If casting succeeds, then the castable expression evaluates to true.

dynEnv |-  Expr cast as AtomicType => Value2

dynEnv |-  Expr castable as AtomicType => true

Otherwise, 'castable as' evaluates to false.

dynEnv |-  not(Expr => Value1)

dynEnv |-  Expr1 castable as AtomicType2 => false

4.12.5 Constructor Functions

Constructor functions provide an alternative syntax for casting.

Normalization

Constructor functions for atomic types are normalized to explicit cast as expressions. Note that the following normalization rule requires to resolve the name of the function call and checks whether than name stands for an atomic type in the static context.

statEnv |-  QName of func expands to expanded-QName
statEnv.typeDefn(expanded-QName) = define type QName2 AtomicTypeDerivation

statEnv |-  [QName(ExprSingle1)]Expr = [ExprSingle1 cast as QName?]Expr

4.12.6 Treat

[55 (XQuery)]    TreatExprXQ    ::=    CastableExpr ( "treat" "as" SequenceType )?

Introduction

The expression "Expr treat as SequenceType", can be used to change the static type of the result of an expression without changing its value. The treat-as expression raises a dynamic error if the dynamic type of the input value does not match the specified type.

Normalization

Treat as expressions are normalized to typeswitch expressions. Note that the following normalization rule uses a variable $fs:new, which is a newly created variable that does not conflict with any variables already in scope.

 
[Expr treat as SequenceType]Expr
==
typeswitch ([ Expr ]Expr)
  case $fs:new as SequenceType return $fs:new
  default $fs:new return fn:error()

4.13 Validate Expressions

[63 (XQuery)]    ValidateExprXQ    ::=    "validate" ValidationMode? "{" Expr "}"
[64 (XQuery)]    ValidationModeXQ    ::=    "lax" | "strict"

Core Grammar

The Core grammar productions for validate are:

[41 (Core)]    ValidateExpr    ::=    "validate" ValidationMode? "{" Expr "}"
[42 (Core)]    ValidationMode    ::=    "lax" | "strict"

A validate expression validates its argument with respect to the in-scope schema definitions, using the schema validation process described in [Schema Part 1]. The argument to a validate expression must be either an element or a document node. Validation replaces all nodes with new nodes that have their own identity, the type annotationXQ, and default values created during the validation process.

Normalization

A validate expression with no validation mode is normalized into a validate expression with the validation mode set to strict.

 
[validate { Expr }]Expr
==
validate strict { [Expr]Expr }
 
[validate ValidationMode { Expr }]Expr
==
validate ValidationMode { [Expr]Expr }

Static Type Analysis

Static typing of the validate operation is defined by the following rule. Note the use of a subtyping check to ensure that the type of the expression to validate is either an element or a well-formed document node (i.e., with only one root element and no text nodes). The type of the expression to validate may be a union of more than one element type. We apply the with mode judgment to each element type to determine the meaning of that element type with the given validation mode, which yields a new element type. The result type is the union over all new element types.

statEnv |-  Expr : Type
statEnv |-  Type <: (element | document { ElementType })
statEnv |-  prime(Type) = ElementType1 | ... | ElementTypen
ElementType1 = element ElementNameOrWildcard1 OptTypeSpecifier1
···
ElementTypen = element ElementNameOrWildcardn OptTypeSpecifiern
statEnv |-  ElementNameOrWildcard1 with mode ValidationMode resolves to ElementType1
···
statEnv |-  ElementNameOrWildcardn with mode ValidationMode resolves to ElementTypen
Type1 = ElementType1 | ... | ElementTypen

statEnv |-  validate ValidationMode { Expr } : Type1

4.13.1 Validating an Element Node

Dynamic Evaluation

The normative dynamic semantics of validation is specified in Section 3.13 Validate ExpressionsXQ. The effect of validation of a data model value is equivalent to:

  • serialization of the data model, as described in [Data Model Serialization], followed by

  • validation of the serialized value into a Post-Schema Validated Infoset, as described in [Schema Part 1], followed by

  • construction of a new data model value, as described in [Data Model].

The above steps are expressed formally by the "erasure" and "annotation" judgments. Formally, validation removes existing type annotations from nodes ("erasure"), and it re-validates the corresponding data model instance, possibly adding new type annotations to nodes ("annotation"). Both erasure and annotation are described formally in [F Auxiliary Judgments for Validation]. Indeed, the conjunction of erasure and annotation provides a formal model for a large part of actual schema validation. The semantics of the validate expression is specified as follows.

In the first premise below, the expression to validate is evaluated. The resulting value must be an element or document node. The second premise constructs a new value in which all existing type annotations have been erased. The third premise determines the element type that corresponds to the element node's name in the given validation mode. The last premise validates erased element node with the type against which it is validated, using the annotate as judgment, yielding the final validated element.

statEnv; dynEnv  |-  Expr => ElementValue1
ElementValue1 erases to ElementValue2
ElementValue2 = element ElementName2 of type TypeName2 { Value }
statEnv |-  ElementName2 with mode ValidationMode resolves to ElementType2
statEnv |-  annotate as ElementType2 ( ElementValue2) => ElementValue3

dynEnv |-  validate ValidationMode { Expr } => ElementValue3

4.13.2 Validating a Document Node

The rule for validating a document node is similar to that for validating an element node.

Dynamic Evaluation

statEnv; dynEnv  |-  Expr => document { ElementValue1 }
document { ElementValue1 } erases to document { ElementValue2 }
ElementValue2 = element ElementName2 of type TypeName2 { Value }
statEnv |-  ElementName2 with mode ValidationMode resolves to ElementType2
statEnv |-  annotate as document { ElementType2 } (document { ElementValue2 }) => document { ElementValue3 }

dynEnv |-  validate ValidationMode { Expr } => document { ElementValue3 }

4.14 Extension Expressions

Introduction

An extension expression is an expression whose semantics are implementation-defined. An extension expression consists of one or more pragmas, followed by an expression enclosed in curly braces.

[65 (XQuery)]    ExtensionExprXQ    ::=    Pragma+ "{" Expr? "}"
[66 (XQuery)]    PragmaXQ    ::=    "(#" S? QName (S PragmaContents)? "#)"
[67 (XQuery)]    PragmaContentsXQ    ::=    (Char* - (Char* '#)' Char*))

Core Grammar

The Core grammar productions for ExtensionExpr are:

[43 (Core)]    ExtensionExpr    ::=    Pragma+ "{" Expr? "}"
[44 (Core)]    Pragma    ::=    "(#" S? QName (S PragmaContents)? "#)"
[45 (Core)]    PragmaContents    ::=    (Char* - (Char* '#)' Char*))

Normalization

Extension expressions are normalized as extension expressions in the [XPath/XQuery] Core.

 
[Pragma+ { Expr }]Expr
==
Pragma+ { [Expr]Expr }

If the extension expression does not contain any expression, this is normalized into an extension expression with a call to the fn:error function.

 
[Pragma+ { }]Expr
==
Pragma+ { fn:error() }

Static Type Analysis

If at least one of the pragmas is recognized, the static semantics are implementation-defined.

If none of the pragmas is recognized, the static semantics are the same as for the input expression. In both cases, the static typing must be applied on the input expression, possibly raising the corresponding type errors.

statEnv |-  Expr : Type1
statEnv |-  A Pragma is recognized, yielding the implementation-defined static type Type2.

statEnv |-  Pragma+ { Expr } : Type2

statEnv |-  Expr : Type1
statEnv |-  No Pragma is recognized.

statEnv |-  Pragma+ { Expr } : Type1

Dynamic Evaluation

The QName of a pragma must resolve to a namespace URI and local name, using the statically known namespaces. If at least one of the pragmas is recognized, the dynamic semantics is implementation-defined.

dynEnv |-  Some Pragma are recognized, yielding the implementation-defined value Value.

dynEnv |-  Pragma+ { Expr } => Value

If none of the pragmas is recognized, the dynamic semantics of an ExtensionExpr are the same as evaluating the given expression.

No Pragma is recognized.      dynEnv |-  Expr => Value

dynEnv |-  Pragma+ { Expr } => Value

5 Modules and Prologs

The organization of this section parallels the organization of Section 4 Modules and PrologsXQ.

Introduction

XQuery supports modules as defined in Section 4 Modules and PrologsXQ. A main moduleXQ contains a PrologXQ followed by a query bodyXQ. A query has exactly one main module. In a main module, the query bodyXQ can be evaluated, and its value is the result of the query. A library moduleXQ contains a module declaration followed by a PrologXQ.

The Prolog is a sequence of declarations that affect query processing. The Prolog can be used, for example, to declare namespace prefixes, import types from XML Schemas, and declare functions and variables. Namespace declarations and schema imports always precede function and variable declarations, as specified by the following grammar productions.

Query Module
[1 (XQuery)]    ModuleXQ    ::=    VersionDecl? (LibraryModule | MainModule)
[3 (XQuery)]    MainModuleXQ    ::=    Prolog QueryBody
[4 (XQuery)]    LibraryModuleXQ    ::=    ModuleDecl Prolog
[6 (XQuery)]    PrologXQ    ::=    ((DefaultNamespaceDecl | Setter | NamespaceDecl | Import) Separator)* ((VarDecl | FunctionDecl | OptionDecl) Separator)*
[7 (XQuery)]    SetterXQ    ::=    BoundarySpaceDecl | DefaultCollationDecl | BaseURIDecl | ConstructionDecl | OrderingModeDecl | EmptyOrderDecl | CopyNamespacesDecl
[8 (XQuery)]    ImportXQ    ::=    SchemaImport | ModuleImport
[9 (XQuery)]    SeparatorXQ    ::=    ";"
[30 (XQuery)]    QueryBodyXQ    ::=    Expr

Function declarations are globally scoped, that is, the use of a function name in a function call may precede declaration of the function. Variable declarations are lexically scoped, i.e., variable declarations must precede variable uses.

Core Grammar

The module declarations and prolog are processed as part of the static and dynamic context processing. In addition, normalization of prolog declarations is performed into a simplified formal grammar given below. As a result, the XQuery core does not need to include the prolog and module declarations. The entry point for the core grammar is the Expr non-terminal, as given in [4 Expressions].

Notation

Modules are identified and can be imported using a target namespace (a URI). In [XPath/XQuery], the process by which a module is obtained from a given target namespace is implementation defined. In this specification, we use the following auxiliary judgment to model that implementation defined process.

The judgment:

AnyURI is target namespace of modules Module1 ... Modulen

holds if Module1 ... Modulen are the modules associated to the target namespace AnyURI, and such as Modulei does not depend directly, or transitively on any module after it. (See [XQuery 1.0: An XML Query Language] for the formal definition of whether a module directly depends on another)

Notation

The XQuery Prolog requires that declarations appear in a particular order. In the Formal Semantics, it is simpler to assume the declarations can appear in any order, as it does not change their semantics -- we simply assume that an XQuery parser has enforced the required order.

The Prolog contains a variety of declarations that specify the initial static and dynamic context of the query. The following formal grammar productions represent any Prolog declaration.

Prolog Declarations
[71 (Formal)]    PrologDeclList    ::=    (PrologDecl Separator PrologDeclList)?
[72 (Formal)]    PrologDecl    ::=    DefaultCollationDecl
| BaseURIDecl
| ConstructionDecl
| OrderingModeDecl
| EmptyOrderDecl
| CopyNamespacesDecl
| SchemaImport
| ModuleImport
| NamespaceDecl
| DefaultNamespaceDecl
| VarDecl
| FunctionDecl
| OptionDecl

The function []PrologDecl takes a prolog declaration and maps it into its equivalent declaration in the Core grammar.

 
[PrologDecl1]PrologDecl
==
PrologDecl2

The following auxiliary judgments are applied when statically processing the declarations in the prolog. The effect of the judgment is to process each prolog declaration in order, constructing a new static environment from the static environment constructed from previous prolog declarations.

The judgment:

AnyURI ; statEnv1 |-  PrologDeclList =>stat statEnv2 with PrologDeclList1

holds if for the given module with namespace AnyURI, and under the static environment statEnv1, the sequence of prolog declarations PrologDeclList yields the static environment statEnv2 and the normalized sequence of prolog declarations in the Core grammar.

The judgment:

statEnv1 |-  PrologDecl =>stat statEnv2

holds if under the static environment statEnv1, the single prolog declaration PrologDecl yields the new static environment statEnv2.

Notation

Because functions can be mutually referential, function signatures must be defined in the static environment before static type analysis is applied to the function bodies. The following judgment is used to extend the static environment with the appropriate function signatures. That judgment is used when computing the static context for a given module before applying static context processing.

The judgment:

statEnv1 |-  PrologDeclList =>sigs statEnv2

holds if extending the static environment statEnv1 with the function signatures declared in PrologDeclList yields the new static environment statEnv2.

This judgment is defined as follows. In case there is no declaration, the static environment is returned unchanged.


statEnv |-  =>sigs statEnv

If the case of a namespace declaration, the static context is extended with the corresponding namespace binding.

PrologDecl = NamespaceDecl or PrologDecl = DefaultNamespaceDecl
statEnv |-  PrologDecl =>stat statEnv1
statEnv1 |-  PrologDeclList =>sigs statEnv2

statEnv |-  PrologDecl ; PrologDeclList =>sigs statEnv2

If the case of a function declaration, the static context is extended with the corresponding signature.

PrologDecl = FunctionDecl
statEnv |-  PrologDecl =>sigs statEnv1
statEnv1 |-  PrologDeclList =>sigs statEnv2

statEnv |-  PrologDecl ; PrologDeclList =>sigs statEnv2

FunctionDecl = declare function QName ( $VarName1 as SequenceType1, ..., $VarNamen as SequenceTypen) as SequenceTyper (EnclosedExpr | external)
statEnv |-  QName of func expands to expanded-QName
[SequenceType1]sequencetype = Type1
...
[SequenceTypen]sequencetype = Typen
[SequenceTyper]sequencetype = Typer
FunctionSig = declare function expanded-QName(Type1, ..., Typen) as Typer
statEnv1 = statEnv + funcType(expanded-QName => FunctionSig)

statEnv |-  FunctionDecl =>sigs statEnv1

For all other kinds of declarations, the static context is left unchanged.

not(PrologDecl = FunctionDecl) and not(PrologDecl = NamespaceDecl) and not(PrologDecl = DefaultNamespaceDecl)

statEnv |-  PrologDecl ; PrologDeclList =>sigs statEnv

In case of a function declaration, the static context is extended with the corresponding function signature.

Static Context Processing

Prolog declarations are processed in the order they are encountered. The normalization of a prolog declaration PrologDecl depends on the static context processing of all previous prolog declarations. In turn, static context processing of PrologDecl depends on the normalization of the PrologDecl. For example, because variables are lexically scoped, the normalization and static context processing of a variable declaration depends on the normalization and static context processing of all previous variable declarations. Therefore, the normalization phase and static context processing are interleaved, with normalization preceding static context processing for each prolog declaration.

The following inference rules express this dependency. The first rule specifies that for an empty sequence of prolog declarations, the initial static environment is left unchanged.


AnyURI ; statEnv |-  =>stat statEnv with

The next two rules interleaves normalization and static context processing. The result of static context processing and normalization is a static context and the normalized prolog declarations. In case the declaration is a module import, the URI for the current module is passed to the static context processing rule. This allows to avoid self-import, which is handled globally (See rules for building the context for module declarations in [5.2 Module Declaration]).

not(PrologDecl = ModuleImport)
[PrologDecl]PrologDecl == PrologDecl1
statEnv |-  PrologDecl1 =>stat statEnv1
AnyURI ; statEnv1 |-  PrologDeclList =>stat statEnv2 with PrologDeclList1

AnyURI ; statEnv |-  PrologDecl ; PrologDeclList =>stat statEnv2 with PrologDecl1 ; PrologDeclList1

PrologDecl = ModuleImport
[PrologDecl]PrologDecl == PrologDecl1
AnyURI ; statEnv |-  PrologDecl1 =>stat statEnv1
AnyURI ; statEnv1 |-  PrologDeclList =>stat statEnv2 with PrologDeclList1

AnyURI ; statEnv |-  PrologDecl ; PrologDeclList =>stat statEnv2 with PrologDecl1 ; PrologDeclList1

Static Type Analysis

Static typing of a main module follows context processing and normalization. Context processing and normalization of a main module applies the rules above to the prolog, then using the resulting static environment statEnv, the query body is normalized into a Core expression, and the static typing rules are applied to this Core expression.

AnyURI ; statEnvDefault |-  PrologDeclList =>stat statEnv with PrologDeclList1
statEnv |-  [QueryBody]Expr == Expr2
statEnv |-  Expr2 : Type

PrologDeclList QueryBody : Type

Notation

Similarly, the judgment:

dynEnv1 |-  PrologDeclList =>dyn dynEnv2

holds if under the dynamic environment dynEnv1, the sequence of prolog declarations PrologDeclList yields the dynamic environment dynEnv2.

The judgment:

dynEnv |-  PrologDecl =>dyn dynEnv1

holds if under the dynamic environment dynEnv, the single prolog declaration PrologDecl yields the new dynamic environment dynEnv1.

Dynamic Context Processing

The rules for initializing the dynamic context are as follows. The first rule specifies that for an empty sequence of prolog declarations, the dynamic environment is left unchanged.


dynEnv |-  =>dyn dynEnv

The second rule simply computes the dynamic environment by processing the prolog declarations in order.

dynEnv |-  PrologDecl =>dyn dynEnv1
dynEnv1 |-  PrologDeclList =>dyn dynEnv2

dynEnv |-  PrologDecl ; PrologDeclList =>dyn dynEnv2

Dynamic Evaluation

Dynamic evaluation of a main module applies the rules for dynamic-context processing to the prolog declarations, then using the resulting dynamic environment dynEnv, the dynamic evaluation rules are applied to the normalized query body.

dynEnvDefault |-  PrologDeclList =>dyn dynEnv
statEnvDefault |-  PrologDeclList =>stat statEnv1
statEnv |-  [QueryBody]Expr == Expr2
dynEnv |-  Expr2 => Value

PrologDeclList QueryBody => Value

Notation

We define a new judgment that maps a module's target namespace (or a main module) to the corresponding module's static environment:

(AnyURI | #MAIN) =>module_statEnv statEnv

We also define a new judgment that maps a module's target namespace (or a main module) to the corresponding module's dynamic environment:

(AnyURI | #MAIN) =>module_dynEnv dynEnv

For a main module, those judgments are defined as follows.

statEnvDefault |-  PrologDeclList =>stat statEnv

#MAIN =>module_statEnv statEnv

dynEnvDefault |-  PrologDeclList =>dyn dynEnv

#MAIN =>module_dynEnv dynEnv

For a library module, those judgments are defined in [5.11 Module Import].

5.1 Version Declaration

[2 (XQuery)]    VersionDeclXQ    ::=    "xquery" "version" StringLiteral ("encoding" StringLiteral)? Separator

Introduction

A version declaration specifies the applicable XQuery syntax and semantics for a module. An XQuery implementation must raise a static error when processing a query labeled with a version that the implementation does not support. This document applies to XQuery 1.0 only and does not specify this static error formally. Verifying whether the proper version declaration is used is not formally specified.

5.2 Module Declaration

Introduction

[5 (XQuery)]    ModuleDeclXQ    ::=    "module" "namespace" NCName "=" URILiteral Separator

We assume that the static-context processing and dynamic-context processing described in [5 Modules and Prologs] are applied to all library modules before the normalization, static context processing, and dynamic context processing of the main module. That is, at the time an "import module" declaration is processed, we assume that the static and dynamic context of the imported module is already available. This assumption does not require or assume separate compilation of modules. An implementation might process all or some imported modules statically (i.e., before the importing module is identified) or dynamically (i.e., when the importing module is identified and processed).

Core Grammar

The core grammar production for module declarations is:

[1 (Core)]    ModuleDecl    ::=    "module" "namespace" NCName "=" URILiteral Separator
[2 (Core)]    Separator    ::=    ";"

Normalization

Module declarations are left unchanged through normalization.

 
[ModuleDecl]PrologDecl
==
ModuleDecl

Static Context Processing

The effect of a module declaration is to apply the static context processing rules defined in [5 Modules and Prologs] to the module's prolog. The resulting static context is then available to any importing module.

The module declaration extends the prolog with a namespace declaration that binds the module's prefix to its target namespace (a URI), then computes the static context for the complete module.

AnyURI is target namespace of modules Module1 ... Modulen
Module1 = module namespace NCName1 = URILiteral; PrologDeclList1
...
Module1 = module namespace NCName1 = URILiteral; PrologDeclListn
dynEnv |-  URILiteral has atomic value AnyURI
statEnvDefault |-  PrologDeclList1 ... PrologDeclListn =>sigs statEnv0
AnyURI ; statEnv0 |-  declare namespace NCName = URILiteral; PrologDeclList1 =>stat statEnv1 with PrologDeclList
...
AnyURI ; statEnvn-1 |-  declare namespace NCName = URILiteral; PrologDeclListn =>stat statEnvn with PrologDeclList

AnyURI =>module_statEnv statEnvn

Note that the rule above and the rules for static context processing of an "import module" declaration in [5.11 Module Import] are mutually recursive.

Dynamic Context Processing

The dynamic context processing of a module declaration is similar to that of static processing. The module declaration extends the prolog with a namespace declaration that binds the module's prefix to its target namespace (a URI), then computes the dynamic context for the complete module.

AnyURI is target namespace of modules Module1 ... Modulen
Module1 = module namespace NCName = URILiteral; PrologDeclList1
...
Modulen = module namespace NCName = URILiteral; PrologDeclListn
dynEnv |-  URILiteral has atomic value AnyURI
dynEnvDefault |-  declare namespace NCName = URILiteral; PrologDeclList1 =>dyn dynEnv1
...
dynEnvn-1 |-  declare namespace NCName = URILiteral; PrologDeclListn =>dyn dynEnvn

AnyURI =>module_dynEnv dynEnvn

Note that the rule above and the rules for dynamic context processing of an "import module" declaration in [5.11 Module Import] are mutually recursive.

5.3 Boundary-space Declaration

[11 (XQuery)]    BoundarySpaceDeclXQ    ::=    "declare" "boundary-space" ("preserve" | "strip")

The semantics of a boundary-space declaration is not specified formally.

5.4 Default Collation Declaration

[19 (XQuery)]    DefaultCollationDeclXQ    ::=    "declare" "default" "collation" URILiteral

Core Grammar

The core grammar production for default collation declarations is:

[11 (Core)]    DefaultCollationDecl    ::=    "declare" "default" "collation" URILiteral

Normalization

Default collation declarations are left unchanged through normalization.

 
[DefaultCollationDecl]PrologDecl
==
DefaultCollationDecl

Static Context Processing

The default collation declaration updates the collations environment component within the static environment. The collations environment component is used by several functions in [Functions and Operators], but is not used in the Formal Semantics.

dynEnv |-  URILiteral has atomic value AnyURI
statEnv.collations(AnyURI) = Collation
statEnv1 = statEnv + defaultCollation(Collation)

statEnv |-  declare default collation URILiteral =>stat statEnv1

Dynamic Context Processing

The default collation declaration does not affect the dynamic context.


dynEnv |-  declare default collation URILiteral =>dyn dynEnv

5.5 Base URI Declaration

[20 (XQuery)]    BaseURIDeclXQ    ::=    "declare" "base-uri" URILiteral

Core Grammar

The core grammar production for base uri declarations is:

[12 (Core)]    BaseURIDecl    ::=    "declare" "base-uri" URILiteral

Normalization

Base URI declarations are left unchanged through normalization.

 
[BaseURIDecl]PrologDecl
==
BaseURIDecl

Static Context Processing

A base URI declaration specifies the base URI property of the static context, which is used when resolving relative URIs within a module.

dynEnv |-  URILiteral has atomic value AnyURI
statEnv1 = statEnv + baseURI(AnyURI)

statEnv |-  declare base-uri URILiteral =>stat statEnv1

Dynamic Context Processing

The base URI declaration does not affect the dynamic context.


dynEnv |-  declare base-uri URILiteral =>dyn dynEnv

5.6 Construction Declaration

[25 (XQuery)]    ConstructionDeclXQ    ::=    "declare" "construction" ("strip" | "preserve")

Core Grammar

The core grammar production for construction declarations is:

[17 (Core)]    ConstructionDecl    ::=    "declare" "construction" ("strip" | "preserve")

Notation

For convenience, we introduce the following auxiliary grammar production.

Constr Mode
[89 (Formal)]    ConstructionMode    ::=    "preserve" | "strip"

Normalization

Construction declarations are left unchanged through normalization.

 
[ConstructionDecl]PrologDecl
==
ConstructionDecl

Static Context Processing

The construction declaration modifies the construction mode in the static context.

statEnv1 = statEnv + constructionMode( ConstructionMode)

statEnv |-  declare construction ConstructionMode =>stat statEnv1

Dynamic Context Processing

The construction declaration does not have any effect on the dynamic context.


dynEnv |-  declare construction ConstructionMode =>stat dynEnv

5.7 Ordering Mode Declaration

[14 (XQuery)]    OrderingModeDeclXQ    ::=    "declare" "ordering" ("ordered" | "unordered")

Core Grammar

The core grammar production for ordering mode declarations is:

[6 (Core)]    OrderingModeDecl    ::=    "declare" "ordering" ("ordered" | "unordered")

Normalization

Ordering mode declarations are left unchanged through normalization.

 
[OrderingModeDecl]PrologDecl
==
OrderingModeDecl

Static Context Processing

The ordering mode declaration does not have any effect on the static context.


statEnv |-  OrderingModeDecl =>stat statEnv

Dynamic Context Processing

The ordering mode declaration does not have any effect on the dynamic context.


dynEnv |-  OrderingModeDecl =>dyn dynEnv

5.8 Empty Order Declaration

[15 (XQuery)]    EmptyOrderDeclXQ    ::=    "declare" "default" "order" "empty" ("greatest" | "least")

Core Grammar

The core grammar production for empty order declarations is:

[7 (Core)]    EmptyOrderDecl    ::=    "declare" "default" "order" "empty" ("greatest" | "least")

Normalization

Empty order declarations are left unchanged through normalization.

 
[EmptyOrderDecl]PrologDecl
==
EmptyOrderDecl

Static Context Processing

The empty order declaration does not have any effect on the static context.


statEnv |-  EmptyOrderDecl =>stat statEnv

Dynamic Context Processing

The empty order declaration does not have any effect on the dynamic context.


dynEnv |-  EmptyOrderDecl =>dyn dynEnv

5.9 Copy-Namespaces Declaration

[16 (XQuery)]    CopyNamespacesDeclXQ    ::=    "declare" "copy-namespaces" PreserveMode "," InheritMode
[17 (XQuery)]    PreserveModeXQ    ::=    "preserve" | "no-preserve"
[18 (XQuery)]    InheritModeXQ    ::=    "inherit" | "no-inherit"

Core Grammar

The core grammar productions for copy-namespaces declarations are:

[8 (Core)]    CopyNamespacesDecl    ::=    "declare" "copy-namespaces" PreserveMode "," InheritMode
[9 (Core)]    PreserveMode    ::=    "preserve" | "no-preserve"
[10 (Core)]    InheritMode    ::=    "inherit" | "no-inherit"

Normalization

Copy-namespace declarations are left unchanged through normalization.

 
[CopyNamespacesDecl]PrologDecl
==
CopyNamespacesDecl

Static Context Processing

The copy-namespace declaration does not have any effect on the static context.


statEnv |-  CopyNamespacesDecl =>stat statEnv

Dynamic Context Processing

The copy-namespace declaration does not have any effect on the dynamic context.


dynEnv |-  CopyNamespacesDecl =>dyn dynEnv

5.10 Schema Import

Schema Imports
[21 (XQuery)]    SchemaImportXQ    ::=    "import" "schema" SchemaPrefix? URILiteral ("at" URILiteral ("," URILiteral)*)?
[22 (XQuery)]    SchemaPrefixXQ    ::=    ("namespace" NCName "=") | ("default" "element" "namespace")

The semantics of Schema Import is described in terms of the [XPath/XQuery] type system. The process of converting an XML Schema into a sequence of type declarations is described in Section [D Importing Schemas]. This section describes how the resulting sequence of type declarations is added into the static context when the Prolog is processed.

Core Grammar

The Core grammar productions for schema imports are:

Schema Imports
[13 (Core)]    SchemaImport    ::=    "import" "schema" SchemaPrefix? URILiteral ("at" URILiteral ("," URILiteral)*)?
[14 (Core)]    SchemaPrefix    ::=    ("namespace" NCName "=") | ("default" "element" "namespace")

Normalization

Schema imports are left unchanged through normalization.

 
[SchemaImport]PrologDecl
==
SchemaImport

Notation

For convenience, we introduce the following auxiliary grammar productions.

Location Hints
[16 (Formal)]    LocationHints    ::=    "at" URILiteral ("," URILiteral)*
[82 (Formal)]    OptLocationHints    ::=    LocationHints?

Notation

The following auxiliary judgments are used when processing schema imports.

The judgment:

statEnv1 |-  Definitions =>type statEnv2

holds if under the static environment statEnv1, the sequence of type definitions Definitions yields the new static environment statEnv2.

The judgment:

statEnv1 |-  Definition =>type statEnv2

holds if under the static environment statEnv1, the single definition Definition yields the new static environment statEnv2.

Static Context Processing

A schema imported into a query is first mapped into the [XPath/XQuery] type system, which yields a sequence of XQuery type definitions. The rules for mapping the imported schema begin in [D.2 Schemas as a whole]. Each type definition in an imported schema is then added to the static environment.

Definitions = [schema URILiteral OptLocationHints]Schema
statEnv |-  Definitions =>type statEnv1

statEnv |-  import schema URILiteral OptLocationHints =>stat statEnv1

The schema import declaration may also assign an element/type namespace prefix to the URI of the imported schema, or assign the default element namespace to the URI of the imported schema.

Definitions = [schema URILiteral OptLocationHints]Schema
statEnv |-  Definitions =>type statEnv1
dynEnv |-  URILiteral has atomic value AnyURI
statEnv2 = statEnv1 + namespace(NCName => (passive, AnyURI))

statEnv |-  import schema namespace NCName = URILiteral OptLocationHints =>stat statEnv2

Definitions = [schema URILiteral OptLocationHints]Schema
statEnv |-  Definitions =>type statEnv1
dynEnv |-  URILiteral has atomic value AnyURI
statEnv2 = statEnv1 + default_elem_namespace( AnyURI)

statEnv |-  import schema default element namespace URILiteral OptLocationHints =>stat statEnv2

An empty sequence of type definitions yields the input environment.


statEnv |-  =>type statEnv

Each type definition is added into the static environment.

statEnv |-  Definitions =>type statEnv1
statEnv1 |-  Definition1 =>type statEnv2

statEnv |-  Definition1 Definitions =>type statEnv2

Each type, element, or attribute declaration is added respectively to the type, element and attribute declarations components of the static environment.

statEnv |-  TypeName of elem/type expands to expanded-QName
statEnv1 = statEnv + typeDefn(expanded-QName => define type TypeName TypeDerivation )

statEnv |-  define type TypeName TypeDerivation =>type statEnv1

statEnv |-  ElementName of elem/type expands to expanded-QName
statEnv1 = statEnv + elemDecl(expanded-QName => define element ElementName OptSubstitution OptNillable TypeReference)

statEnv |-  define element ElementName OptSubstitution OptNillable TypeReference =>type statEnv1

statEnv |-  AttributeName of attr expands to expanded-QName
statEnv1 = statEnv + attrDecl(expanded-QName => define attribute AttributeName TypeReference)

statEnv |-  define attribute AttributeName TypeReference =>type statEnv1

Note that it is a static error to import two schemas that both define the same name in the same symbol space and in the same scope. That is multiple top-level definitions of the same type, element, or attribute name raises a static error. For instance, a query may not import two schemas that include top-level element declarations for two elements with the same expanded name.

Dynamic Context Processing

The schema import declarations do not affect the dynamic context.


dynEnv |-  SchemaImport =>dyn dynEnv

5.11 Module Import

[23 (XQuery)]    ModuleImportXQ    ::=    "import" "module" ("namespace" NCName "=")? URILiteral ("at" URILiteral ("," URILiteral)*)?

Introduction

The effect of an "import module" declaration is to extend the importing module's dynamic (and static) context with the global variables (and their types) and the functions (and their signatures) of the imported module. Module import is not transitive, only the global variables and functions declared explicitly in the imported module are available in the importing module. Also, module import does not import schemas, therefore the importing module must explicitly import any schemas on which the imported global variables or functions depend.

Core Grammar

The core grammar production for module imports is:

Module Import
[15 (Core)]    ModuleImport    ::=    "import" "module" ("namespace" NCName "=")? URILiteral ("at" URILiteral ("," URILiteral)*)?

Normalization

Module imports are left unchanged through normalization.

 
[ModuleImport]PrologDecl
==
ModuleImport

Notation

The rules below depend on the following auxiliary functions which are used to import the proper fragment of the static context.

The function fs:local-variables(statEnv, AnyURI) returns all the (expanded-QName, Type) pairs in statEnv.varType such that the URI part of the variable's expanded-QName equals the given URI, that is, the variables that are declared locally in the module with the given namespace URI.

The function fs:local-functions(statEnv, AnyURI) returns all the function signatures in statEnv.funcType such that the URI part of the function's expanded-QName equals the given URI, that is, the function signatures that are declared locally in the module with the given namespace URI.

Notation

The following auxiliary judgments is used to extend a given static environment with the static environment from an imported module.

The judgment

statEnv1 extended with static environment statEnv2 yields statEnv3 for uri AnyURI1

holds if extending the environment statEnv1 with the environment statEnv2 yields the environment statEnv3 under the given namespace uri AnyURI.

This judgment is defined as follows.

fs:local-variables(statEnv2, AnyURI) = (Variable1,Type1) ... (Variablem,Typem)
statEnv3 = statEnv1 + varType(Variable1 => Type1 ... ; Variablem => Typem)
fs:local-functions(statEnv2, AnyURI) = (expanded-QName1,FunctionSig1) ... (expanded-QNamen,FunctionSign)
statEnv4 = statEnv3 + funcType(expanded-QName1 => FunctionSig1; ... ;expanded-QNamen => FunctionSign)

statEnv1 extended with static environment statEnv2 yields statEnv4 for uri AnyURI1

Notation

The rules below depend on the following auxiliary judgments.

The following rules add each variable explicitly declared in the imported module to the importing module's dynamic variable environment.


dynEnv1 ; AnyURI |-  =>import_variables dynEnv1

dynEnv2 = dynEnv1 + varValue(expanded-QName1 => #IMPORTED(AnyURI))
dynEnv2 ; AnyURI |-  (expanded-QName2, Type2), ···, (expanded-QNamen, Typen) =>import_variables dynEnv3

dynEnv1 ; AnyURI |-  (expanded-QName1, Type1), ···, (expanded-QNamen, Typen) =>import_variables dynEnv3

The following rules add each function explicitly declared in the imported module to the importing module's dynamic function environment.


dynEnv1 ; AnyURI |-  =>import_functions dynEnv1

dynEnv2 = dynEnv1 + funcDefn((expanded-QName1(Type1,1, ..., Type1,n)) => #IMPORTED(AnyURI))
dynEnv2 ; AnyURI |-  (expanded-QName2(Type2,1, ..., Type2,n)), ···, (expanded-QNamek(Typek,1, ..., Typek,n)) =>import_functions dynEnv3

dynEnv1 ; AnyURI |-  (expanded-QName1(Type1,1, ..., Type1,n)), ···, (expanded-QNamek(Typek,1, ..., Typek,n)) =>import_functions dynEnv3

Notation

The following auxiliary judgments is used to extend a given dynamic environment with the dynamic environment from an imported module.

The judgment

dynEnv1 extended with dynamic environment dynEnv2 yields dynEnv3 for uri AnyURI

holds if extending the dynamic environment dynEnv1 with the dynamic environment dynEnv2 yields the dynamic environment dynEnv3 under the given namespace uri AnyURI.

This judgment is defined as follows.

dynEnv1 ; AnyURI |-  fs:local-variables(statEnv2, AnyURI) =>import_variables dynEnv3
dynEnv1 ; AnyURI |-  fs:local-variables(statEnv2, AnyURI) =>import_variables dynEnv3
dynEnv3 ; AnyURI |-  fs:local-functions(statEnv2, AnyURI) =>import_functions dynEnv4

dynEnv1 extended with dynamic environment dynEnv2 yields dynEnv4 for uri AnyURI

Static Context Processing

The first set of premises below "look up" the static contexts of all the imported modules, as defined in [5.2 Module Declaration]. The second set of premises extend the input static context with the global variables and function signatures declared in the imported static contexts.

not(AnyURI1 = AnyURI)
AnyURI1 =>module_statEnv statEnv1
statEnv extended with static environment statEnv1 yields statEnv2 for uri AnyURI1

AnyURI ; statEnv |-  import module AnyURI1 LocationHints? =>stat statEnv2

AnyURI1 = AnyURI

AnyURI ; statEnv |-  import module AnyURI1 LocationHints? =>stat statEnv1

not(AnyURI1 = AnyURI)
dynEnv |-  URILiteral1 has atomic value AnyURI1
AnyURI1 =>module_statEnv statEnv1
statEnv extended with static environment statEnv1 yields statEnv2 for uri AnyURI1
statEnv3 = statEnv2 + namespace(NCName => (passive, AnyURI))

statEnv |-  import module namespace NCName = URILiteral1 LocationHints? =>stat statEnv3

AnyURI1 = AnyURI
dynEnv |-  URILiteral1 has atomic value AnyURI1
statEnv2 = statEnv1 + namespace(NCName => (passive, AnyURI))

statEnv |-  import module namespace NCName = URILiteral1 LocationHints? =>stat statEnv2

Note that the rules above and the rules for processing a library module in [5.2 Module Declaration] above are mutually recursive. It is possible to define the semantics in that way, since XQuery forbids the use of recursive modules.

Dynamic Context Processing

During dynamic context processing, each variable and function name is mapped to the special value #IMPORTED(AnyURI) to indicate that the variable or function is defined in the imported module with the given URI.

The first set of premises below "look up" the dynamic contexts of all the imported modules, as defined in [5.2 Module Declaration]. The second set of premises extend the input dynamic context with the global variables and functions declared in the imported dynamic contexts.

dynEnv |-  URILiteral has atomic value AnyURI
AnyURI =>module_dynEnv dynEnv1
...
AnyURI =>module_dynEnv dynEnvn
dynEnv extended with dynamic environment dynEnv1 yields dynEnv1' for uri AnyURI
...
dynEnvn-1 extended with dynamic environment dynEnvn yields dynEnvn' for uri AnyURI

dynEnv1 |-  import module (namespace NCName =)? URILiteral LocationHints? =>dyn dynEnvn'

Note that the rule above and the rules for processing a library module in [5.2 Module Declaration] above are mutually recursive. It is possible to define the semantics in that way, since XQuery forbids the use of recursive modules.

5.12 Namespace Declaration

[10 (XQuery)]    NamespaceDeclXQ    ::=    "declare" "namespace" NCName "=" URILiteral

Core Grammar

The core grammar production for namespace declarations is:

[3 (Core)]    NamespaceDecl    ::=    "declare" "namespace" NCName "=" URILiteral

Normalization

Namespace declarations are left unchanged through normalization.

 
[NamespaceDecl]PrologDecl
==
NamespaceDecl

Static Context Processing

A namespace declaration adds a new (prefix,uri) binding in the namespace component of the static environment. All namespace declarations in the prolog are passive declarations. Namespace declaration attributes of element constructors are active declarations.

dynEnv |-  URILiteral has atomic value AnyURI
statEnv1 = statEnv + namespace(NCName => (passive, AnyURI))

statEnv |-  declare namespace NCName = URILiteral =>stat statEnv1

In case the URILiteral part of a namespace declaration is a zero-length string, the namespace prefix is marked as #UNDECLARED in the static context.

statEnv1 = statEnv + namespace(NCName => (passive, #UNDECLARED))

statEnv |-  declare namespace NCName = "" =>stat statEnv1

Dynamic Context Processing

The namespace declaration does not affect the dynamic context.


dynEnv |-  declare namespace NCName = URILiteral =>dyn dynEnv

5.13 Default Namespace Declaration

[12 (XQuery)]    DefaultNamespaceDeclXQ    ::=    "declare" "default" ("element" | "function") "namespace" URILiteral

Core Grammar

The core grammar production for default namespace declarations is:

[4 (Core)]    DefaultNamespaceDecl    ::=    "declare" "default" ("element" | "function") "namespace" URILiteral

Normalization

Default namespace declarations are left unchanged through normalization.

 
[DefaultNamespaceDecl]PrologDecl
==
DefaultNamespaceDecl

Static Context Processing

A default element namespace declaration changes the default element namespace component of the static environment. If the URI literal is the zero-length string, the default element namespace is set to the null namespace.

statEnv1 = statEnv + default_elem_namespace(#NULL-NAMESPACE)

statEnv |-  declare default element namespace "" =>stat statEnv1

not(URILiteral = "")
dynEnv |-  URILiteral has atomic value AnyURI
statEnv1 = statEnv + default_elem_namespace( AnyURI)

statEnv |-  declare default element namespace URILiteral =>stat statEnv1

A default function namespace declaration changes the default function namespace component of the static environment. If the URI literal is the zero-length string, the default function namespace is set to the null namespace.

statEnv1 = statEnv + default_function_namespace(#NULL-NAMESPACE)

statEnv |-  declare default function namespace "" =>stat statEnv1

not(URILiteral = "")
dynEnv |-  URILiteral has atomic value AnyURI
statEnv1 = statEnv + default_function_namespace( AnyURI)

statEnv |-  declare default function namespace URILiteral =>stat statEnv1

Note that multiple declarations of the same namespace prefix in the Prolog result in a static error. However, a declaration of a namespace in the Prolog can override a prefix that has been predeclared in the static context.

Dynamic Context Processing

Default namespace declarations do not affect the dynamic context.


dynEnv |-  DefaultNamespaceDecl =>dyn dynEnv

5.14 Variable Declaration

[24 (XQuery)]    VarDeclXQ    ::=    "declare" "variable" "$" QName TypeDeclaration? ((":=" ExprSingle) | "external")

Core Grammar

The core grammar production for variable declarations is:

[16 (Core)]    VarDecl    ::=    "declare" "variable" "$" QName TypeDeclaration? ((":=" ExprSingle) | "external")

Normalization

Normalization of a variable declaration normalizes its initializing expression, if it is present.

 
[ declare variable $VarName as SequenceType := Expr ]PrologDecl
==
declare variable $VarName as SequenceType := [Expr]Expr
 
[ declare variable $VarName := Expr ]PrologDecl
==
declare variable $VarName := [Expr]Expr

If an external variable declaration does not have a type declaration it is treated as if the type declaration was item()*.

 
[ declare variable $VarName external ]PrologDecl
==
declare variable $VarName as item()* external
 
[ declare variable $VarName as SequenceType external ]PrologDecl
==
declare variable $VarName as SequenceType external

Static Context Processing

A variable declaration updates the variable component of the static context by associating the given variable with a static type.

If a variable declaration has an associated expression but does not have a type declaration, the static type of the variable is the static type of the expression.

statEnv  |-  VarName of var expands to Variable
statEnv |-  Expr : Type
statEnv1 = statEnv + varType( Variable => Type)

statEnv |-  declare variable $VarName := Expr =>stat statEnv1

If the variable declaration has an associated expression and has a type declaration, the static type of the variable is the specified type. The type of the expression must be a subtype of the declared type.

statEnv  |-  VarName of var expands to Variable
Type = [SequenceType]sequencetype
statEnv |-  Expr : Type2
statEnv |-  Type2 <: Type
statEnv1 = statEnv + varType( Variable => Type)

statEnv |-  declare variable $VarName as SequenceType := Expr =>stat statEnv2

If the variable declaration is external and has a type declaration, the static type of the variable is the specified type.

statEnv  |-  VarName of var expands to Variable
Type = [SequenceType]sequencetype
statEnv1 = statEnv + varType( Variable => Type)

statEnv |-  declare variable $VarName as SequenceType external =>stat statEnv2

Dynamic Context Processing

To evaluate a variable declaration, its associated expression is evaluated, and the dynamic context is updated with the variable bound to the resulting value.

dynEnv |-  Expr => Value
statEnv  |-  VarName of var expands to Variable
dynEnv1 = dynEnv + varValue( Variable => Value)

dynEnv |-  declare variable $VarName := Expr =>dyn dynEnv1

dynEnv |-  Expr => Value
Type = [ SequenceType ]sequencetype
statEnv  |-  Value matches Type
statEnv  |-  VarName of var expands to Variable
dynEnv1 = dynEnv + varValue( Variable => Value)

dynEnv |-  declare variable $VarName as SequenceType := Expr =>dyn dynEnv1

Dynamic evaluation does not apply to externally defined variables. The dynamic environment must provide the values of external variables in the initial dynamic context (dynEnvDefault).


dynEnv |-  declare variable $VarName as SequenceType external =>dyn dynEnv

5.15 Function Declaration

Introduction

User-defined functions specify the name of the function, the names and types of the parameters, and the type of the result. The function body defines how the result of the function is computed from its parameters.

Function declarations
[26 (XQuery)]    FunctionDeclXQ    ::=    "declare" "function" QName "(" ParamList? ")" ("as" SequenceType)? (EnclosedExpr | "external")
[27 (XQuery)]    ParamListXQ    ::=    Param ("," Param)*
[28 (XQuery)]    ParamXQ    ::=    "$" QName TypeDeclaration?

Core Grammar

The core grammar productions for function declarations are:

Function declarations
[18 (Core)]    FunctionDecl    ::=    "declare" "function" QName "(" ParamList? ")" ("as" SequenceType)? (EnclosedExpr | "external")
[19 (Core)]    ParamList    ::=    Param ("," Param)*
[20 (Core)]    Param    ::=    "$" QName TypeDeclaration?

Notation

The following auxiliary mapping rule is used for the normalization of parameters in function declarations: []Param.

Parameters without a declared type are given the item()* sequence type.

 
[$VarName]Param
==
$VarName as item()*
 
[$VarName as SequenceType ]Param
==
$VarName as SequenceType

An empty parameter list is left unchanged.

 
[]Param
==

A parameter list is normalized by applying the normalization rule to each parameter.

 
[ Param1, ..., Paramn ]Param
==
[ Param1 ]Param, ..., [ Paramn ]Param

Normalization

The parameter list and body of a user-defined function are all normalized into Core expressions.

statEnv |-  QName of func expands to expanded-QName
Type = [SequenceType]sequencetype

statEnv |-  [ declare function QName ( ParamList? ) as SequenceType { Expr } ]PrologDecl = declare function QName ( [ParamList?]Param ) as SequenceType { [Expr]FunctionArgument(Type) }

If the return type of the function is not provided, it is given the item()* sequence type.

 
[declare function QName ( ParamList? ) { Expr }]PrologDecl
==
[declare function QName ( ParamList? ) as item()* { Expr }]PrologDecl

Externally defined functions are normalized similarly.

 
[ declare function QName ( ParamList? ) as SequenceType external]PrologDecl
==
declare function QName( [ParamList?]Param ) as SequenceType external
 
[declare function QName ( ParamList? ) external ]PrologDecl
==
[declare function QName ( ParamList? ) as item()* external ]PrologDecl

Notation

We use the following auxiliary judgment during static context processing and static type analysis of function declarations.

The judgment:

statEnv |-  function declaration FunctionDecl with signature FunctionSig : Type

holds if the function declaration FunctionDecl with the signature FunctionSig has the type Type.

Static Context Processing

Static context processing accesses the function signature from the static context, and checks that the function declaration corresponds to the declared type.

statEnv.funcType(expanded-QName,n) = FunctionSig
statEnv |-  function declaration FunctionDecl with signature FunctionSig : Typer

statEnv |-  FunctionDecl =>stat statEnv1

Note that the static context processing is performing type checking of the function, as defined below. Note also that the type checking is done in the new environment in which the function declaration has been added which ensures that recursive calls are type-checked properly.

Static Type Analysis

The static typing rules for function bodies follow normalization and processing of the static context. The static typing rules below construct a new environment in which each parameter has the given expected type, then the static type of the function's body is computed under the new environment. The function body's type must be a subtype of the expected return type. If static typing fails, a static type error is raised. Otherwise, static typing of the function has no other effect, as function signatures are already inside the static environment.

statEnv.varType |-  Expr : Type
statEnv |-  Type <: Typer

statEnv |-  function declaration declare function QName () as SequenceTyper { Expr } with signature declare function expanded-QName() as Typer : Typer

statEnv  |-  VarName1 of var expands to Variable1
...
statEnv  |-  VarNamen of var expands to Variablen
statEnv + varType( Variable1 => Type1 ;...; Variablen => Typen )  |-  Expr : Type
statEnv |-  Type can be promoted to Typer

statEnv |-  function declaration declare function QName ($VarName1 as SequenceType1, ···, $VarNamen as SequenceTypen) as SequenceTyper { Expr } with signature declare function expanded-QName(Type1, ..., Typen) as Typer : Typer

The bodies of external functions are not available and therefore cannot by type checked. To ensure type soundness, the implementation must guarantee that the value returned by the external function matches the expected return type.


statEnv |-  function declaration declare function QName () as SequenceTyper external with signature declare function expanded-QName() as Typer : Typer

statEnv  |-  VarName1 of var expands to Variable1
...
statEnv  |-  VarNamen of var expands to Variablen

statEnv |-  function declaration declare function QName ( $VarName1 as SequenceType1, ···, $VarNamen as SequenceTypen ) as SequenceTyper external with signature declare function expanded-QName(Type1, ..., Typen) as Typer : Typer

Dynamic Context Processing

A function declaration updates the dynamic context. The function name with arity N is associated with the given function body. The number of arguments is required, because XQuery permits overloading of function names as long as each function signature has a different number of arguments.

statEnv |-  QName of func expands to expanded-QName
dynEnv1 = dynEnv + funcDefn(expanded-QName() => (Expr))

dynEnv |-  declare function QName () as SequenceTyper { Expr } =>dyn dynEnv1

statEnv |-  QName of func expands to expanded-QName
statEnv |-  VarName1 of var expands to Variable1
···
statEnv  |-  VarNamen of var expands to Variablen
[SequenceType1]sequencetype = Type1
...
[SequenceTypen]sequencetype = Typen
dynEnv1 = dynEnv + funcDefn(expanded-QName(Type1,...,Typen) => ( Expr , Variable1 , ···, Variablen))

dynEnv |-  declare function QName ( $VarName1 as SequenceType1, ···, $VarNamen as SequenceTypen ) as SequenceTyper { Expr } =>dyn dynEnv1

An external function declaration does not affect the dynamic environment. The implementation must support the declared external functions.


dynEnv |-  declare function QName ( $VarName1 as SequenceType1, ···, $VarNamen as SequenceTypen ) as SequenceTyper external =>dyn dynEnv

The dynamic semantics of a function body are applied when the function is called, as described in [4.1.5 Function Calls].

5.16 Option Declaration

[13 (XQuery)]    OptionDeclXQ    ::=    "declare" "option" QName StringLiteral

Core Grammar

The core grammar production for option declarations is:

[5 (Core)]    OptionDecl    ::=    "declare" "option" QName StringLiteral

Normalization

Option declarations are left unchanged through normalization.

 
[OptionDecl]PrologDecl
==
OptionDecl

Static Context Processing

An option declaration does not have any effect on the static context.


statEnv |-  OptionDecl =>stat statEnv

Dynamic Context Processing

An option declaration does not have any effect on the dynamic context.


dynEnv |-  OptionDecl =>dyn dynEnv

6 Conformance

The XQuery Formal Semantics is intended primarily as a component that can be used by [XQuery 1.0: An XML Query Language], or a host language of [XML Path Language (XPath) 2.0]. Therefore, the XQuery Formal Semantics relies on specifications that use it (such as [XPath 2.0], [XSLT 2.0], and [XQuery]) to specify conformance criteria in their respective environments. Specifications that set conformance criteria for their use of the formal semantics must not relax the constraints expressed in this specification.

6.1 Static Typing Feature

This specification normatively defines the static typing feature which can be used in [XQuery 1.0: An XML Query Language] or a host language of [XML Path Language (XPath) 2.0]. The static typing feature is specified using the static typing judgment introduced in [3.2.3 Static typing judgment].

6.1.1 Static Typing Extensions

In some cases, the static typing rules are not very precise (see, for example, the type inference rules for the ancestor axes—parent, ancestor, and ancestor-or-self—and for the function fn:root). If an implementation supports a static typing extension, it must always provide a more precise type than the one defined in this specification.

This constraint is formally expressed as follows. A static typing extension Expr :ext Type must be such that for every expression Expr the following holds.

statEnv |-  Expr : Type
statEnv |-  Type' <: Type

statEnv |-  Expr :ext Type'

Note:

It is not recommended for a static typing extension to change the static typing behavior of expressions that specify a type explicitly (treat as, cast as, typeswitch, function parameters, and type declarations in variable bindings), since the purpose of those expressions is to impose a specific type.

7 Additional Semantics of Functions

This section defines the auxiliary functions required to define the formal semantics of [XPath/XQuery], and gives special normalization and static typing rules for some functions in [Functions and Operators].

Remember from [4.1.5 Function Calls] that the following rules operate after namespace resolution for the function name, and directly over the input type of the parameters. In the rest of the section, we will use the following shortcuts notations for specific relevant URIs:

7.1 Formal Semantics Functions

Introduction

This section gives the definition and semantics of functions that are used in the formal semantics but are not in [Functions and Operators]. Their dynamic semantics are defined in the same informal style as in the [Functions and Operators] document. The static semantics of some formal-semantics functions require custom static typing rules.

7.1.1 The fs:convert-operand function

fs:convert-operand($actual as xs:anyAtomicType?, $expected as xs:anyAtomicType) as xs:anyAtomicType ?

The formal-semantics function fs:convert-operand converts the operands of arithmetic and comparison operators as follows:

  1. If $actual is the empty sequence, returns the empty sequence.

  2. If $actual is an instance of type xs:untypedAtomic, then

    1. if $expected is an instance of type xs:untypedAtomic or xs:string, returns $actual cast to xs:string;

    2. if $expected is of numeric type, returns $actual cast to xs:double

    3. otherwise returns $actual cast to the type of $expected.

  3. Otherwise, returns $actual.

Static Type Analysis

No conversion is needed unless $actual is an instance of type xs:untypedAtomic.

statEnv  |-  not(Type1 <: xs:untypedAtomic?)

statEnv |-  (FS-URI,"convert-operand")(Type1, Type2) : Type1

Pairs of untyped atomic operands are converted to strings.

statEnv |-  Type1 <: xs:untypedAtomic ?
statEnv |-  Type2 <: xs:untypedAtomic

statEnv |-  (FS-URI,"convert-operand")(Type1, Type2) : xs:string · quantifier (Type1)

When an untyped operand is paired with a numeric operand, it is converted to xs:double.

statEnv |-  Type1 <: xs:untypedAtomic ?
statEnv |-  Type2 <: fs:numeric

statEnv |-  (FS-URI,"convert-operand")(Type1, Type2) : xs:double · quantifier (Type1)

Finally, an untyped atomic operand not dealt with by the above rules is converted to the type of the other operand.

statEnv |-  Type1 <: xs:untypedAtomic ?
statEnv |-  Type2 <: xs:anyAtomicType
statEnv  |-  not(Type2 <: (xs:untypedAtomic|fs:numeric))

statEnv |-  (FS-URI,"convert-operand")(Type1, Type2) : Type2 · quantifier(Type1)

7.1.2 The fs:convert-simple-operand function

fs:convert-simple-operand($actual as xs:anyAtomicTypeAtomic *, $expected as xs:anyAtomicType) as xs:anyAtomicTypeAtomic *

The formal-semantics function fs:convert-simple-operand is used to convert the value of the $actual argument such that it matches the type of the $expected argument (or matches a sequence of that type).

The dynamic semantics of this function are as follows:

  • For each item in $actual argument that is of type xs:untypedAtomic, that item is cast to the type of the $expected argument, and the resulting sequence is returned.

Static Type Analysis

The following static typing rules correspond to the dynamic semantics rules given above.

statEnv |-  Type2 <: xs:anyAtomicType
Type3 = convert_untypedAtomic(prime(Type1), Type2)

statEnv |-  (FS-URI,"convert-simple-operand")(Type1, Type2) : Type3 · quantifier(Type1)

7.1.3 The fs:distinct-doc-order function

fs:distinct-doc-order($nodes as node *) as node *

The fs:distinct-doc-order function sorts its input sequence of nodes by document order and removes duplicates.

Static Type Analysis

The fs:distinct-doc-order function expects a sequence of nodes as input. The resulting type is computed using prime and quantifier, which are defined in [8.4 Judgments for FLWOR and other expressions on sequences].

statEnv  |-  Type <: node*

statEnv |-  (FS-URI,"distinct-doc-order") ( Type ) : prime(Type) · quantifier(Type)

7.1.4 The fs:distinct-doc-order-or-atomic-sequence function

fs:distinct-doc-order-or-atomic-sequence($item as item()*) as item()*

The fs:distinct-doc-order-or-atomic-sequence function operates on either an homogeneous sequence of nodes or an homogeneous sequence of atomic values. If the input is a sequence of nodes, is sorts those nodes by document order and removes duplicates, using the fs:distinct-doc-order function. If it is a sequence of atomic values, it returns it unchanged.

Static Type Analysis

The fs:distinct-doc-order function expects either a sequence of nodes as input or a sequence of atomic values. The resulting type is computed using prime and quantifier, which are defined in [8.4 Judgments for FLWOR and other expressions on sequences].

statEnv  |-  Type <: NodeType*

statEnv |-  (FS-URI,"distinct-doc-order-or-atomic-sequence") ( Type ) : prime(Type) · quantifier(Type)

statEnv  |-  Type <: xs:anyAtomicType*

statEnv |-  (FS-URI,"distinct-doc-order-or-atomic-sequence") ( Type ) : Type

7.1.5 The fs:item-sequence-to-node-sequence function

fs:item-sequence-to-node-sequence($items as item()*) as node()*

The fs:item-sequence-to-node-sequence function converts a sequence of item values to nodes by applying the normative rules numbered 1, 2, 3 after the sentence "Processing of the computed element constructor proceeds as follows:" in Section 3.7.3.1 Computed Element ConstructorsXQ.

Static Type Analysis

statEnv |-  Type <: attribute*, (element|document|text|processing-instruction|comment|xs:string|xs:float| ...|xs:NOTATION)*

statEnv |-  (FS-URI,"item-sequence-to-node-sequence") (Type) : attribute*, (element|text|processing-instruction|comment)*

7.1.6 The fs:item-sequence-to-node-sequence-doc function

fs:item-sequence-to-node-sequence-doc($items as item()*) as node()*

The fs:item-sequence-to-node-sequence-doc function converts a sequence of item values to nodes by applying the normative rules numbered 1, 2, 3 after the sentence "Processing of the document node constructor then proceeds as follows:" in Section 3.7.3.3 Document Node ConstructorsXQ.

Static Type Analysis

statEnv |-  Type <: (element|document|text|processing-instruction|comment|xs:string|xs:float| ...|xs:NOTATION)*

statEnv |-  (FS-URI,"item-sequence-to-node-sequence-doc") (Type) : (element|text|processing-instruction|comment)*

7.1.7 The fs:item-sequence-to-untypedAtomic function

Introduction

fs:item-sequence-to-untypedAtomic($items as item()*) as xs:untypedAtomic

The fs:item-sequence-to-untypedAtomic function converts a sequence of item values to a string of type xs:untypedAtomic by applying the normative rules in Section 3.7.3.2 Computed Attribute ConstructorsXQ for processing the content expression.

Dynamic Evaluation

If the input of the fs:item-sequence-to-untypedAtomic function is an empty sequence, it returns a zero-length string. Otherwise, each atomic value in the input sequence is cast into a string. The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair.

Static Type Analysis

There are no special static typing rules for this function. Static type analysis for this function should be performed as for a built-in function declared with the given signature.

7.1.8 The fs:item-sequence-to-untypedAtomic-PI function

Introduction

fs:item-sequence-to-untypedAtomic-PI($items as item()*) as xs:untypedAtomic

The fs:item-sequence-to-untypedAtomic-PI function converts a sequence of item values to a string of type xs:untypedAtomic by applying the normative rules in Section 3.7.3.5 Computed Processing Instruction ConstructorsXQ for processing the content expression.

Dynamic Evaluation

If the input is an empty sequence, the fs:item-sequence-to-untypedAtomic-PI function returns a zero-length string. Otherwise, each atomic value in the input sequence is cast into a string. If any of the resulting strings contains the string "?>", a dynamic error is raised. The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair. Leading whitespace is removed from the resulting string.

Static Type Analysis

There are no special static typing rules for this function. Static type analysis for this function should be performed as for a built-in function declared with the given signature.

7.1.9 The fs:item-sequence-to-untypedAtomic-text function

Introduction

fs:item-sequence-to-untypedAtomic-text($items as item()*) as xs:untypedAtomic?

The fs:item-sequence-to-untypedAtomic-text function converts a sequence of item values to a string of type xs:untypedAtomic, or empty, by applying the rules in Section 3.7.3.4 Text Node ConstructorsXQ for processing the content expression.

Dynamic Evaluation

If the input is the empty sequence, the fs:item-sequence-to-untypedAtomic-text function returns the empty sequence. Otherwise, each atomic value in the input sequence is cast into a string. The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair.

Static Type Analysis

There are no special static typing rules for this function. Static type analysis for this function should be performed as for a built-in function declared with the given signature.

7.1.10 The fs:item-sequence-to-untypedAtomic-comment function

Introduction

fs:item-sequence-to-untypedAtomic-comment($items as item()*) as xs:untypedAtomic

The fs:item-sequence-to-untypedAtomic-comment function converts a sequence of item values to a string of type xs:untypedAtomic by applying the normative rules in Section 3.7.3.6 Computed Comment ConstructorsXQ for processing the content expression.

Dynamic Evaluation

If the input is the empty sequence, the fs:item-sequence-to-untypedAtomic-comment function returns a zero-length string. Otherwise, each atomic value in the input sequence is cast into a string. The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair. It is a dynamic error if the result of the content expression of a computed comment constructor contains two adjacent hyphens or ends with a hyphen.

Static Type Analysis

There are no special static typing rules for this function. Static type analysis for this function should be performed as for a built-in function declared with the given signature.

7.1.11 The fs:apply-ordering-mode function

fs:apply-ordering-mode($items as item()*) as item()*

Dynamic Evaluation

If the statEnv.orderingMode is set to ordered, the fs:apply-ordering-mode function is the identity function, returning its input sequence in its original order.

statEnv.orderingMode = ordered      dynEnv  |-  Expr => Value

dynEnv  |-  fs:apply-ordering-mode(Expr) => Value

If the statEnv.orderingMode is set to unordered, the fs:apply-ordering-mode is equivalent to the fn:unordered function, returning the items from its input sequence in arbitrary order.

statEnv.orderingMode = unordered      dynEnv  |-  fn:unordered(Expr) => Value

dynEnv  |-  fs:apply-ordering-mode(Expr) => Value

Static Type Analysis

If the ordering context is set to ordered, the static type of the input expression of the fs:apply-ordering-mode function is left unchanged.

statEnv.orderingMode = ordered

statEnv  |-  (FS-URI,"apply-ordering-mode")(Type) : Type

If the ordering context is set to unordered, the static type of the input expression of the fs:apply-ordering-mode function is computed using the prime and quantifier judgments, as for the fn:unordered function.

statEnv.orderingMode = unordered

statEnv  |-  (FS-URI,"apply-ordering-mode")(Type) : prime(Type) · quantifier(Type)

7.1.12 The fs:to function

fs:to($firstval as xs:integer?, $lastval as xs:integer?) as xs:integer*

The formal semantics function fs:to is a wrapper function for the op:to operator, taking the semantics of the range expression over empty sequences into account.

Dynamic Evaluation

If one of the input parameters for fs:to is the empty sequence, the function returns the empty sequence, otherwise it returns the result of calling the op:to operator. This semantics is equivalent to the following user-defined function.

declare function fs:to($firstval as xs:integer?, $lastval as xs:integer?) as xs:integer* {
  if (fn:empty($firstval) or fn:empty($lastval)
  then ()
  else op:to($firstval,$lastval)
};

Static Type Analysis

The static type of fs:to does not require any additional static typing rule, and is typed as a function call based on the above signature.

7.2 Standard functions with specific static typing rules

Introduction

This section gives special normalization and static typing rules for functions in [Functions and Operators] for which the standard normalization or static typing rules are not appropriate. All functions that are not mentioned behave as described in Section [4.1.5 Function Calls]. When given, the static typing rules in this section always give more precise type information than the generic rule based on the function's signature.

7.2.1 The fn:last context function

As explained in [3.1.2 Dynamic Context], the fn:last() context function is modeled using the Formal Semantics variable $fs:last. For that function the following static typing and dynamic evaluation rules apply.

Static Type Analysis

statEnv.varType((FS-URI,"last")) = Type

statEnv |-  (FN-URI,"last")()