Please refer to the errata for this document, which may include some normative corrections.
See also translations.
This document is also available in these non-normative formats: XML and Change markings relative to first edition.
Copyright © 2010 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This document defines formally the semantics of XQuery 1.0 [XQuery 1.0: An XML Query Language (Second Edition)] XPath 2.0 [XML Path Language (XPath) 2.0 (Second Edition)].
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 one document in a set of eight documents that are being progressed to Edited Recommendation together (XPath 2.0, XQuery 1.0, XQueryX 1.0, XSLT 2.0, Data Model (XDM), Functions and Operators, Formal Semantics, Serialization).
This document, published on 14 December 2010, is an Edited Recommendation of the W3C. It supersedes the previous W3C Recommendation of 23 January 2007. This second edition is not a new version of this specification; its purpose is to clarify a number of issues that have become apparent since the first edition was published. All of these clarifications (excepting trivial editorial fixes) have been published in a separate errata document, and published in a Proposed Edited Recommendation in April 2009. The changes are summarized in an appendix. This document has been jointly developed by the W3C XML Query Working Group and the W3C XSL Working Group, each of which is part of the XML Activity.
This document has been reviewed by W3C Members, by software developers, and by other W3C groups and interested parties, and is endorsed by the Director as a W3C Recommendation. It is a stable document and may be used as reference material or cited from another document. W3C's role in making the Recommendation is to draw attention to the specification and to promote its widespread deployment. This enhances the functionality and interoperability of the Web.
This document incorporates changes made against the Recommendation of 23 January 2007 that resolve all errata known at the date of publication. Changes to this document since the first edition are detailed in the [G Changes since the First Edition]. This document supersedes the first edition.
This specification is designed to be referenced 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 the XQuery 1.0 implementation report and the XSLT 2.0 implementation report (member-only) for details.
Please report errors in and submit comments on this document using 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 report, whether made in Bugzilla or in email. Each Bugzilla entry and email message should contain only one error report. Archives of the comments and responses are available at http://lists.w3.org/Archives/Public/public-qt-comments/.
This document is not being further developed for future versions of XPath or XQuery.
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) must disclose the information in accordance with section 6 of the W3C Patent Policy.
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-string
function
7.1.7 The
fs:item-sequence-to-untypedAtomic-PI function
7.1.8 The
fs:item-sequence-to-untypedAtomic-text function
7.1.9 The
fs:item-sequence-to-untypedAtomic-comment function
7.1.10 The fs:apply-ordering-mode
function
7.1.11 The fs:to function
7.1.12 The fs:node-sequence function
7.1.13 The fs:item-at 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 and fn:not functions
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
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 Changes since the First
Edition (Non-Normative)
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:
[XQuery 1.0: An XML Query Language (Second Edition)] introduces the XQuery 1.0 language, defines its capabilities from a user-centric view, and defines the language syntax.
[XML Path Language (XPath) 2.0 (Second Edition)] introduces the XPath 2.0 language, defines its capabilities from a user-centric view, and defines the language syntax.
[XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)] lists the functions and operators defined for the [XPath/XQuery] language and specifies the required types of their parameters and return value.
[XQuery 1.0 and XPath 2.0 Data Model (Second Edition)] formally specifies the data model used by [XPath/XQuery] to represent the content of XML documents. The [XPath/XQuery] language is formally defined by operations on this data model.
[XSLT 2.0 and XQuery 1.0 Serialization (Second Edition)] specifies how [XPath/XQuery] data model values are serialized into XML.
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 (Second Edition)] and [XML Path Language (XPath) 2.0 (Second Edition)] 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 [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)] 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.
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 (Second Edition)] and [XML Path Language (XPath) 2.0 (Second Edition)]. 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.
This section provides the background necessary to understand the Formal Semantics, introduces the notations that are used, and explains its relationship to other documents.
Why a Formal Semantics? The goal of the formal semantics is to complement the [XPath/XQuery] specification ([XQuery 1.0: An XML Query Language (Second Edition)] and [XML Path Language (XPath) 2.0 (Second Edition)]), 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].
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 (Second Edition)] document, and are marked with "(XQuery)". For instance, the following production describes FLWOR expressions in XQuery.
[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 (Second Edition)], and are marked with "(XPath)". For instance, the following production describes for expressions in XPath.
[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.
[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 (Second Edition)] document. In these cases, specific grammar productions are introduced. Notably, additional productions are used to describe values in the [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)], 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.
[39 (Formal)] | Definition |
::= | ("define" "element" ElementName OptSubstitution OptNillable TypeReference) |
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.
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
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
holds if the expression Expr yields (or evaluates to) the value Value.
The judgment
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
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
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
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].
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
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 new environment is used for the evaluation
of the expression $x + 2
. Then this second environment
is updated 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.
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.
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 |- 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.
|
||||||
|
||||||
|
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.
|
||||
|
||||
|
or
|
|||||
|
|||||
|
etc.
When ellipses are used, the value for the index always ranges from 1 to an arbitrary number n.
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.
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.
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 [XQuery 1.0 and XPath 2.0 Functions and
Operators (Second Edition)] 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.
dm: for accessors of the [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)].
op: for operators in [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)].
fs: for functions and types defined in the formal semantics.
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.
The [XPath/XQuery] language is defined over values of the [XPath/XQuery] data model. The [XPath/XQuery] data model is defined normatively in [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)]. 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 [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)] are assumed to hold.
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.
[7 (Formal)] | Value |
::= | Item |
[21 (Formal)] | Item |
::= | NodeValue |
[22 (Formal)] | AtomicValue |
::= | AtomicValueContent TypeAnnotation? |
[1 (Formal)] | AtomicValueContent |
::= | String |
[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 |
[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 |
[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 Formal Semantics.
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 (Second Edition)]. XQuery does not support the namespace axis and does not represent namespace bindings in the form of nodes.
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 }
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.
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 describes 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 instance 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] describes top-level type declarations.
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.
[25 (Formal)] | FormalItemType |
::= | AtomicTypeName |
NodeType |
[28 (Formal)] | AtomicTypeName |
::= | TypeName |
[26 (Formal)] | NodeType |
::= | DocumentType |
[27 (Formal)] | ElementContentType |
::= | ElementType |
[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 |
[93 (Formal)] | ProcessingInstructionType |
::= | "processing-instruction" PITargetOrWildcard |
[94 (Formal)] | PITargetOrWildcard |
::= | NCName | "*" |
[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
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].
[24 (Formal)] | Type |
::= | FormalItemType |
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 described above is general enough to capture the type inferred for an arbitrary expression. 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 |
[43 (Formal)] | ElementModel |
::= | ElementType |
Top level definitions correspond to global element declarations, global attribute declarations and type definitions in XML Schema.
[40 (Formal)] | Definitions |
::= | (Definition Separator Definitions)? |
[39 (Formal)] | Definition |
::= | ("define" "element" ElementName OptSubstitution OptNillable TypeReference) |
[76 (Formal)] | OptSubstitution |
::= | Substitution? |
[41 (Formal)] | Substitution |
::= | "substitutes" "for" ElementName |
[33 (Formal)] | TypeDerivation |
::= | ComplexTypeDerivation |
AtomicTypeDerivation |
[34 (Formal)] | ComplexTypeDerivation |
::= | OptDerivation
OptMixed "{" Type? "}" |
[35 (Formal)] | AtomicTypeDerivation |
::= | "restricts" AtomicTypeName |
[95 (Formal)] | OptDerivation |
::= | Derivation? |
[37 (Formal)] | Derivation |
::= | ("restricts" 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 positiveInteger, element postcode of type ipo:UKPostcode };
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 follows
define type SKU restricts xsd:string;
Example
When the type derivation is omitted, the type derives by
restriction from xs:anyType
. For instance, the
following two type definitions are equivalent:
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
followed 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 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
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;
The [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)] 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 [XQuery 1.0 and
XPath 2.0 Functions and Operators (Second Edition)] 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
function 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].
The organization of this section parallels the organization of Section 2 BasicsXQ.
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.
Notation
We introduce the following auxiliary grammar production to describe function signatures.
[85 (Formal)] | FunctionSig |
::= | "declare" "function" expanded-QName "(" TypeList? ")" "as" Type |
[86 (Formal)] | TypeList |
::= | Type ("," Type)* |
In the static (and dynamic) context, each function is uniquely identified by its expanded QName and its arity (number of parameters). We introduce the auxilliary symbol FunctionKey to encapsulate this combination.
[92 (Formal)] | FunctionKey |
::= | expanded-QName "," Arity |
(Arity is understood to be a non-negative integer.)
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 |
|
|||||
statEnv.namespace |
|
|||||
statEnv.default_elem_namespace |
|
|||||
statEnv.default_function_namespace |
|
|||||
statEnv.typeDefn |
|
|||||
statEnv.elemDecl |
|
|||||
statEnv.attrDecl |
|
|||||
statEnv.varType |
|
|||||
statEnv.funcType |
|
|||||
statEnv.collations |
|
|||||
statEnv.defaultCollation |
|
|||||
statEnv.constructionMode |
|
|||||
statEnv.orderingMode |
|
|||||
statEnv.defaultEmptySequenceOrder |
|
|||||
statEnv.boundarySpace |
|
|||||
statEnv.copyNamespacesMode |
|
|||||
statEnv.baseURI |
|
|||||
statEnv.docType |
|
|||||
statEnv.collectionType |
|
|||||
statEnv.defaultCollectionType |
|
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.
|
|||
|
|||
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 an expression) 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.
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
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) |
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 |
|
|||||
dynEnv.funcDefn |
|
|||||
dynEnv.dateTime |
|
|||||
dynEnv.timezone |
|
|||||
dynEnv.docValue |
|
|||||
dynEnv.collectionValue |
|
|||||
dynEnv.defaultCollectionValue |
|
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.
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.
The following figure depicts the [XPath/XQuery] processing model
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:
Parsing. (Step SQ1 in Figure 1). The grammar for the [XPath/XQuery] syntax is defined in [XQuery 1.0: An XML Query Language (Second Edition)]. Parsing may generate syntax errors. If no error occurs, an internal operation tree of the parsed query is created.
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.
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.
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).
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.
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:
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].
Data Model Generation. Expressions are evaluated on values in the [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)]. XML documents must be loaded into the [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)] before the evaluation phase. This is described in the [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)] and is not discussed further here.
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 [XSLT 2.0 and XQuery 1.0 Serialization (Second Edition)] 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 (Second Edition)] document and more details about parsing for XPath 2.0 can be found in the [XML Path Language (XPath) 2.0 (Second Edition)] document. No further discussion of parsing is included here.
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:
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.
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.
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
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.
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
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.
Expressions can raise errors during static analysis or dynamic
evaluation. The [XQuery 1.0 and XPath
2.0 Functions and Operators (Second Edition)] [XQuery 1.0: An XML Query Language (Second Edition)],
and [XML Path Language (XPath) 2.0 (Second
Edition)] 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 (Second Edition)]. Instead, this document describe the rules necessary to statically detect the subset of the [XPath/XQuery] dynamic errors known as type errorXQ.
[XPath/XQuery] is most generally used to process documents. The representation of a document is normatively defined in [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)]. The functions used to access documents and collections are normatively defined in [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)].
Document order is defined in [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)].
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.
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.
[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 [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)].
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 (Second Edition)].
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 }
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
[XQuery 1.0 and XPath 2.0 Functions and
Operators (Second Edition)]. The normative definitions of typed
value and string value are defined in [XQuery 1.0 and XPath 2.0 Data Model (Second
Edition)].
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.
[119 (XQuery)] | SequenceTypeXQ |
::= | ("empty-sequence" "(" ")") |
[121 (XQuery)] | ItemTypeXQ |
::= | KindTest | ("item" "("
")") | AtomicType |
[120 (XQuery)] | OccurrenceIndicatorXQ |
::= | "?" | "*" | "+" |
[122 (XQuery)] | AtomicTypeXQ |
::= | QName |
[123 (XQuery)] | KindTestXQ |
::= | DocumentTest |
[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" "(" ")") |
[78 (Core)] | ItemType |
::= | KindTest | ("item" "("
")") | AtomicType |
[77 (Core)] | OccurrenceIndicator |
::= | "?" | "*" | "+" |
[79 (Core)] | AtomicType |
::= | QName |
[80 (Core)] | KindTest |
::= | DocumentTest |
[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.
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.
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.
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 * |
[processing-instruction(NCName)]sequencetype |
== |
processing-instruction NCName |
For backward compatibility with XPath 1.0, the PITarget of a PITest may also be expressed as a string literal. The following rule handles that case.
|
|||
|
|||
[processing-instruction(StringLiteral)]sequencetype = processing-instruction NCName |
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
) |
[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.
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 |
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 |
[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 |
During static analysis, it is a type error for an expression to have the empty type, except for the following expressions and function calls:
Empty parentheses ()
, which denote the empty
sequence.
The fn:data
function and all functions in the
fs namespace applied to empty parentheses
()
.
Any function which returns the empty type.
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.
|
||||
|
||||
|
In general, static type errors are raised whenever there are no static typing rules which can compute the type of a given expression. This is the reason for the absence of a formal conclusion in this rule. 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.
Primary expressions are the basic primitives of the language. They include literals, variables, function calls, and the parenthesized expressions.
[84 (XQuery)] | PrimaryExprXQ |
::= | Literal | VarRef | ParenthesizedExpr | ContextItemExpr | FunctionCall | OrderedExpr | UnorderedExpr | Constructor |
Core Grammar
The Core grammar production for primary expressions is:
[55 (Core)] | PrimaryExpr |
::= | Literal | VarRef | ParenthesizedExpr | FunctionCall | OrderedExpr | UnorderedExpr | Constructor |
Introduction
A literal is a direct syntactic representation of an atomic value. [XPath/XQuery] supports two kinds of literals: string literals and numeric 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:
[56 (Core)] | Literal |
::= | NumericLiteral |
StringLiteral |
[57 (Core)] | NumericLiteral |
::= | IntegerLiteral |
DecimalLiteral | DoubleLiteral |
[99 (Core)] | IntegerLiteral |
::= | Digits |
[100 (Core)] | DecimalLiteral |
::= | ("." Digits) | (Digits "." [0-9]*) |
[101 (Core)] | DoubleLiteral |
::= | (("." Digits) | (Digits ("." [0-9]*)?)) [eE] [+-]? Digits |
[102 (Core)] | StringLiteral |
::= | ('"' (EscapeQuot |
[^"])* '"') | ("'" (EscapeApos
| [^'])* "'") |
[97 (Core)] | URILiteral |
::= | StringLiteral |
[113 (Core)] | Digits |
::= | [0-9]+ |
Notation
To define the dynamic semantics of literals, we introduce the following auxiliary judgments.
The judgment
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 (Second Edition)]. Notably, this judgment deals with handling of literal overflows for numeric literals, and handling of character references, and predefined entity references for string literals.
Literals are left unchanged through normalization.
[IntegerLiteral]Expr |
== |
IntegerLiteral |
[DecimalLiteral]Expr |
== |
DecimalLiteral |
[DoubleLiteral]Expr |
== |
DoubleLiteral |
[StringLiteral]Expr |
== |
StringLiteral |
The static type of a literal expression is its corresponding atomic type.
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.
|
||
|
||
|
Introduction
A variable evaluates to the value to which the variable's QName is bound in the dynamic context.
[87 (XQuery)] | VarRefXQ |
::= | "$" VarName |
[88 (XQuery)] | VarNameXQ |
::= | QName |
Core Grammar
The Core grammar productions for variable references are:
[58 (Core)] | VarRef |
::= | "$" VarName |
[59 (Core)] | VarName |
::= | QName |
Variable references are left unchanged through normalization.
In the static semantics, the type of a variable is simply its type in the static environment statEnv.varType:
|
|||
|
|||
|
If the variable is not bound in the static environment, a static type error is raised.
In the dynamic semantics, a locally declared variable is evaluated by "looking up" its value in dynEnv.varValue:
|
|||
|
|||
|
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].
[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.)
Empty parentheses ()
evaluate to the empty
sequence.
[90 (XQuery)] | ContextItemExprXQ |
::= | "." |
Introduction
A context item expression evaluates to the context item, which may be either a node or an atomic value.
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.
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.
[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:
[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
.
Each argument expression in a function call is normalized to its corresponding Core expression by applying []FunctionArgument(Type) where Type is the corresponding parameter type.
|
||||
|
||||
statEnv |- [QName (Expr1, ..., Exprn)]Expr = QName ( [Expr1]FunctionArgument(Type1), ..., [Exprn]FunctionArgument(Typen) ) |
Note that this normalization rule depends on the function signature (found in statEnv.funcType), which is used to get the types of the function parameters (Type1, ..., Typen).
Different sets of static typing rules are used to type check function calls depending on which of the following categories they 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 factor out the step (common to all those categories) of translating a type-inference judgment on syntactic objects (QName and Expri) into a type-inference judgment on semantic objects (expanded-QName and Typei).
|
|||
|
|||
|
|
||||||
|
||||||
|
The following depends on the kind of function call.
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.
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.
Otherwise, the following general static typing rules are applied.
Recall that statEnv.funcType contains at most one function signature for any given (function name, arity) pair. The two following rules look up the function in the static environment and check that the type of each actual argument 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.
|
||
|
||
|
|
|||||
|
|||||
|
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.
Notation
The following auxiliary judgment
holds when applying the function with expanded QName expanded-QName and no parameter yields the value 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).
The following rules apply to all the different kinds of functions using the previously defined judgment.
|
||||||
|
||||||
|
|
||||||||||||
|
||||||||||||
|
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].
|
||||
|
||||
|
|
||||
|
||||
|
Note that the function body is evaluated in the dynamic environment containing the main module declarations.
The rule for evaluating a 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.
|
|||||||||
|
|||||||||
|
|
||||||||||||
|
||||||||||||
|
If the function is a built-in function (resp. special formal semantics function), the value returned by the function is the one specified in [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)] (resp. [7.1 Formal Semantics Functions] or [C.2 Mapping of Overloaded Internal Functions]).
|
|||
|
|||
|
|
|||
|
|||
|
If the function is an external function, the value returned by the function is implementation-defined.
|
|||
|
|||
|
|
|||
|
|||
|
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.
[68 (XQuery)] | PathExprXQ |
::= | ("/" 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.
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.
[/ 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 | |||||||
== | |||||||
|
Note that this section uses some auxiliary judgments which are defined in [8.2 Judgments for step expressions and filtering].
Introduction
[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:
[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 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 | ||
== | ||
|
[ForwardStep PredicateList [
fn:last () ]]Expr |
|||
== | |||
|
When predicates are applied on a reverse step, the position variable is bound in reverse document order.
[ReverseStep PredicateList [ NumericLiteral ]]Expr | ||||
== | ||||
|
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 |
||
== | ||
|
The normalization rules above all use the function fs:item-at
to select a
particular item. The static typing rules for this function are
defined in [7.1.13 The fs:item-at
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 | ||||
== | ||||
|
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 | |||||
== | |||||
|
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) |
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 |- 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.
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 |- 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.
Introduction
The XQuery grammar for forward and reverse axis is as follows.
[73 (XQuery)] | ForwardAxisXQ |
::= | ("child" "::") |
[76 (XQuery)] | ReverseAxisXQ |
::= | ("parent" "::") |
In the case of XPath, forward axis also contain the
namespace::
axis.
[30 (XPath)] | ForwardAxisXP |
::= | ("child" "::") |
Core Grammar
The Core grammar productions for XPath axis are:
[49 (Core)] | ForwardAxis |
::= | ("child" "::") |
[51 (Core)] | ReverseAxis |
::= | ("parent" "::") |
Notation
We introduce the following auxiliary grammar production to describe all axis.
[90 (Formal)] | Axis |
::= | ForwardAxis |
ReverseAxis |
Notation
The normalization of axes uses the following auxiliary mapping rule: []Axis.
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 |
|||
== | |||
[
|
[following:: NodeTest]Axis |
|||||
== | |||||
[
|
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 |
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.
[78 (XQuery)] | NodeTestXQ |
::= | KindTest | NameTest |
[79 (XQuery)] | NameTestXQ |
::= | QName | Wildcard |
[80 (XQuery)] | WildcardXQ |
::= | "*" |
Core Grammar
The Core grammar productions for node tests are:
[52 (Core)] | NodeTest |
::= | KindTest | NameTest |
[53 (Core)] | NameTest |
::= | QName | Wildcard |
[54 (Core)] | Wildcard |
::= | "*" |
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.
[18 (Formal)] | Prefix |
::= | NCName |
[19 (Formal)] | LocalPart |
::= | NCName |
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.
Predicates in path expressions are normalized with a special mapping rule:
[Expr]Predicates | |||
== | |||
|
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.
The corresponding Section in the [XPath/XQuery] document just contains examples.
[74 (XQuery)] | AbbrevForwardStepXQ |
::= | "@"? NodeTest |
[77 (XQuery)] | AbbrevReverseStepXQ |
::= | ".." |
Here are normalization rules for the abbreviated syntax.
[..]Axis |
== |
parent::node() |
[@NodeTest]Axis |
== |
attribute::NodeTest |
[NodeTest]Axis |
== |
child::NodeTest |
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.
[31 (XQuery)] | ExprXQ |
::= | ExprSingle (","
ExprSingle)* |
[49 (XQuery)] | RangeExprXQ |
::= | AdditiveExpr (
"to" AdditiveExpr
)? |
Core Grammar
The Core grammar production for sequence expressions is:
[22 (Core)] | Expr |
::= | ExprSingle (","
ExprSingle)* |
A sequence expression is normalized into a sequence of normalized single expressions:
The type of the sequence expression is the sequence over the types of the individual expressions.
Each expression in the sequence is evaluated and the resulting values are concatenated into one sequence.
The range operator is normalized to the
fs:to
function.
The static semantics of the fs:to
function
is defined in [7.1.11 The fs:to
function].
The dynamic semantics of the fs:to
function is defined in [7.1.11 The fs:to
function].
Introduction
[81 (XQuery)] | FilterExprXQ |
::= | PrimaryExpr
PredicateList |
Core Grammar
There are no Core grammar productions for filter expressions as they are normalized to other Core expressions.
When a predicate with a numeric literal or the
last()
expression is applied on a primary expression,
it is normalized using the fs:item-at
function. This
results in a more precise static type for those cases.
[PrimaryExpr PredicateList [ NumericLiteral ]]Expr | ||
== | ||
|
[PrimaryExpr PredicateList [ fn:last() ]]Expr | |||
== | |||
|
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 | ||||
== | ||||
|
There are no additional static typing rules for filter expressions.
There are no additional dynamic evaluation rules for filter expressions.
[XPath/XQuery] provides several operators for combining sequences of nodes.
[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 |
Operators for combining node sequences are normalized as follows.
[Expr1 SequenceOp Expr2]Expr |
== |
fs:apply-ordering-mode
([SequenceOp]SequenceOp (
[Expr1]Expr,
[Expr2]Expr )) |
The static semantics of the operators that combine sequences are defined in [7.2.14 The op:union, op:intersect, and op:except operators].
The dynamic semantics for function calls is given in [4.1.5 Function Calls].
[XPath/XQuery] provides arithmetic operators for addition, subtraction, multiplication, division, and modulus, in their usual binary and unary forms.
[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 function []ArithOp is defined by the following table:
ArithOp | [ArithOp]ArithOp |
"+" | fs:plus |
"-" | fs:minus |
"*" | fs:times |
"div" | fs:div |
"mod" | fs:mod |
Core Grammar
There are no Core grammar productions for arithmetic expressions as they are normalized to other Core expressions.
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 | ||||
== | ||||
|
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 |
||||
== | ||||
|
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 (fs:convert-operand (fn:data (([Expr]Expr)),
1.0E0)) |
The static semantics for function calls is given in [4.1.5 Function Calls]. The mapping from the overloaded internal functions to the corresponding non-overloaded function is given in [C.2 Mapping of Overloaded Internal Functions].
The dynamic semantics for function calls is given in [4.1.5 Function Calls]. The mapping from the overloaded internal functions to the corresponding non-overloaded function is given in [C.2 Mapping of Overloaded Internal Functions].
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.
[48 (XQuery)] | ComparisonExprXQ |
::= | RangeExpr ( (ValueComp |
[61 (XQuery)] | ValueCompXQ |
::= | "eq" | "ne" | "lt" | "le" | "gt" | "ge" |
[60 (XQuery)] | GeneralCompXQ |
::= | "=" | "!=" | "<" | "<=" | ">" |
">=" |
[62 (XQuery)] | NodeCompXQ |
::= | "is" | "<<" | ">>" |
Notation
The mapping function []ValueComp is defined by the following table:
ValueComp | [ValueComp]ValueComp |
"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.
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 ValueComp Expr2]Expr | ||||
== | ||||
|
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 [XQuery 1.0 and XPath
2.0 Functions and Operators (Second Edition)].
The dynamic semantics for function calls is given in [4.1.5 Function Calls].
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
The function []GeneralComp is defined by the following table:
GeneralComp | [GeneralComp]GeneralComp |
"= " |
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.
The normalization rule for a general comparison expression first
atomizes each argument by applying fn:data
, resulting
in two sequences of atomic values. Two nested some
expressions then examine (potentially) every pair of values (one
value from each sequence). For each pair, the internal function
fs:convert-operand
is called twice; if either of the two values is of type xs:untypedAtomic
, one of
the calls will cast it to a type determined by the other value. The
overloaded internal function corresponding to the general
comparison operator is then applied to the two converted
values.
[Expr1 GeneralComp Expr2]Expr | |||||
== | |||||
|
Core Grammar
There are no Core grammar productions for node comparisons as they are normalized to other Core expressions.
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].
The static semantics for the internal functions are defined in [C.2 Mapping of Overloaded Internal Functions].
The dynamic semantics for internal function is defined in [C.2 Mapping of Overloaded Internal Functions].
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
.
[46 (XQuery)] | OrExprXQ |
::= | AndExpr ( "or" AndExpr )* |
[47 (XQuery)] | AndExprXQ |
::= | ComparisonExpr (
"and" ComparisonExpr
)* |
Core Grammar
The Core grammar productions for logical expressions are:
[36 (Core)] | OrExpr |
::= | AndExpr ( "or" AndExpr )* |
[37 (Core)] | AndExpr |
::= | CastableExpr ( "and"
CastableExpr )* |
The normalization rules for "and
" and
"or
" first get the effective boolean value of each
argument, then apply the appropriate Core operator.
The logical expressions require that each subexpression have
type xs:boolean
. The result type is also
xs:boolean
.
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.
[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.
Core Grammar
The Core grammar productions for constructors are:
[64 (Core)] | Constructor |
::= | ComputedConstructor |
[65 (Core)] | ComputedConstructor |
::= | CompDocConstructor |
[21 (Core)] | EnclosedExpr |
::= | "{" Expr "}" |
There are no Core grammar productions for direct XML element or attribute constructors as they are normalized to computed constructors.
Introduction
The static and dynamic semantics of the direct forms of element and attribute constructors are specified in terms of the equivalent computed element and attribute constructors.
Notation
The auxiliary mapping rules []ElementContent, []ElementContentUnit, []PartitionIntoUnits, and []DirCharsUnit 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 DirCharsUnit ( a maximal contiguous sequence of literal characters , CDataSections, 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>
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.
Adjacent element-content units 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.
[ElementContentUnit1, ..., ElementContentUnitn]ElementContent |
== |
[ ElementContentUnit1 ]ElementContentUnit , ..., [ ElementContentUnitn]ElementContentUnit |
(Note that this rule should be understood to cover the degenerate cases of n=0 and n=1, where the element constructor's content consists of zero or one element-content units.)
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 a maximal contiguous sequence of individual characters that include literal characters, CDataSections, 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 ]DirCharsUnit } |
The application of []DirCharsUnit to DirCharsUnit is defined informally. It produces a string literal corresponding to the content of the DirCharsUnit, in which boundary whitespace is processed as specified in Section 3.7.1.4 Boundary WhitespaceXQ, 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 into a
call to the function fs:item-sequence-to-node-sequence
,
which implements various rules for converting a sequence of atomic
values and nodes into a sequence of nodes before element
construction.
[ { Expr } ]ElementContentUnit |
== |
fs:item-sequence-to-node-sequence ((
[Expr]Expr )) |
There are no additional static typing rules for direct XML element or attribute constructors.
There are no additional dynamic evaluation rules for direct XML element or attribute constructors.
Like direct element constructors, direct attribute constructors are normalized to computed attribute constructors.
Notation
The auxiliary mapping rules []Attribute, []DirAttributeValue, []AttributeContent, []AttributeContentUnit, and []AttributeCharsUnit, 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 |
::= | AttributeCharsUnit | EnclosedExpr |
[91 (Formal)] | AttributeCharsUnit |
::= | (QuotAttrContentChar |
AposAttrContentChar |
EscapeQuot | EscapeApos | PredefinedEntityRef |
CharRef | "{{" |
"}}")+ |
An AttributeCharsUnit is required to be maximal, i.e., it must extend as far as possible in both directions. In other words, an AttributeContentUnits must not contain two adjacent AttributeCharsUnits.
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.
[
|
|||
== | |||
|
Namespace-declaration attributes, i.e.,
those attributes whose prefix is xmlns
are ignored by
mapping them to the empty sequence.
|
||
== | ||
() |
All attributes that are not namespace-declaration attributes are mapped to computed attribute constructors.
|
||
== | ||
attribute Prefix:LocalPart { [ [DirAttributeValue]DirAttributeValue ]AttributeContent } |
The effect of [DirAttributeValue]DirAttributeValue is not specified formally; informally, it partitions the content of DirAttributeValue into a sequence of AttributeContentUnits, each of which is either an enclosed expression (EnclosedExpr) or a maximal run of character content (AttributeCharsUnit). These content units are then normalized via []AttributeContent, which is defined below.
To apply []AttributeContent to zero or more
attribute-content units, we normalize each unit individually and
construct a sequence of the normalized results. Then we apply the
function fn:string-join
, which will concatenate the
values of the normalized units.
[ AttributeContentUnit1 ... AttributeContentUnitn ]AttributeContent |
== |
fn:string-join (([ AttributeContentUnit1 ]AttributeContentUnit , ..., [ AttributeContentUnitn]AttributeContentUnit) , '' ) |
(Note that this rule should be understood to cover the degenerate cases of n=0 and n=1, where the attribute constructor's content consists of zero or one attribute-content units.)
The next two rules specify the normalization of each attribute-content unit via []AttributeContentUnit.
We normalize an AttributeCharsUnit (i.e., a maximal run of attribute-content characters, including literal characters, character references, predefined entity references, escaped curly braces, and escaped single and double quotes) by converting it into a string literal.
[ AttributeCharsUnit ]AttributeContentUnit |
== |
[ AttributeCharsUnit ]AttributeCharsUnit |
The effect of [AttributeCharsUnit]AttributeCharsUnit is not specified formally; informally, it unescapes any escaped braces or quotes, performs attribute value normalization as specified in Section 3.7.1.1 AttributesXQ, and then represents the resulting string value as a string literal.
We normalize an enclosed expression into a call to the function
fs:item-sequence-to-string
,
which implements various rules for converting a sequence of atomic
values and nodes into a string.
[ { Expr } ]AttributeContentUnit |
== |
fs:item-sequence-to-string ((
[ Expr ]Expr )) |
Notation
The auxiliary mapping rules []NamespaceAttr, and []NamespaceAttrs are defined in this section and are used for the normalization of namespace declaration attributes.
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.
[
|
|||
== | |||
|
Attributes whose prefix is not xmlns
are ignored by
mapping them to the empty sequence.
|
||
== | ||
() |
Namespace-declaration attributes are normalized to local namespace declarations (LocalNamespaceDecl). The content of such attributes must be defined with a URI literal.
|
||
== | ||
namespace LocalPart { URILiteral } |
The rules for normalizing element content are given above in [4.7.1 Direct Element Constructors].
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 []DirCharsUnit.
[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.
[Char*]Characters takes the character content of a PI or comment constructor and yields a corresponding StringLiteral.
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 |
There are no additional static typing rules for direct processing-instruction or comment constructors.
There are no additional dynamic evaluation rules for direct processing-instruction or comment constructors.
[109 (XQuery)] | ComputedConstructorXQ |
::= | CompDocConstructor |
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 (Second Edition)].
[111 (XQuery)] | CompElemConstructorXQ |
::= | "element" (QName | ("{"
Expr "}")) "{" ContentExpr? "}" |
[112 (XQuery)] | ContentExprXQ |
::= | Expr |
Core Grammar
The Core grammar productions for computed element constructors are:
[67 (Core)] | CompElemConstructor |
::= | "element" (QName | ("{"
Expr "}")) "{" ContentExpr "}" "{" LocalNamespaceDecls
"}" |
[69 (Core)] | ContentExpr |
::= | Expr |
[98 (Core)] | LocalNamespaceDecls |
::= | LocalNamespaceDecl* |
[68 (Core)] | LocalNamespaceDecl |
::= | "namespace" NCName "{"
URILiteral "}" |
If the content expression is missing, the computed element constructor is normalized as if its content expression was the empty sequence.
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.
|
||||||||||
|
||||||||||
|
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 attribute nodes at the beginning.
|
|||||
|
|||||
statEnv1 |- element QName {
Expr } { LocalNamespaceDecls }
: element
QName of type xs:anyType |
|
|||||
|
|||||
statEnv1 |- element QName {
Expr } { LocalNamespaceDecls }
: 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
.
|
|||||||
|
|||||||
statEnv1 |- element {
Expr1 } {
Expr2 } { LocalNamespaceDecls }
: element * of
type xs:anyType |
|
|||||||
|
|||||||
statEnv1 |- element {
Expr1 } {
Expr2 } { LocalNamespaceDecls }
: element * of
type xs:untyped |
Notation
The following auxiliary judgment is used in the dynamic semantics of node constructors.
This judgment is informally defined to hold when Value1 is obtained by applying the following modifications to Value0:
Adjacent text nodes in Value0 are merged into a single text node by concatenating their contents, with no intervening blanks.
After concatenation, any text node whose content is a zero-length string is deleted from the sequence.
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 constructor's 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 its value's text nodes are processed. The resulting sequence 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.
|
|||||
|
|||||
statEnv; dynEnv |-
element QName { Expr } {} => element QName of type
xs:anyType { Value1 } { } |
|
|||||||||||||||||||
|
|||||||||||||||||||
statEnv; dynEnv |-
element QName { Expr } { LocalNamespaceDecls }
=> element
QName of type xs:anyType { Value1 } { 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
.
[113 (XQuery)] | CompAttrConstructorXQ |
::= | "attribute" (QName |
("{" Expr "}")) "{" Expr? "}" |
Core Grammar
The Core grammar production for computed attribute constructors is:
[70 (Core)] | CompAttrConstructor |
::= | "attribute" (QName | ("{"
Expr "}")) "{" Expr "}" |
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-string
function.
[attribute QName { Expr }]Expr |
== |
attribute
QName { fs:item-sequence-to-string
(([Expr]Expr)) } |
[attribute { Expr1 } { Expr2 }]Expr |
== |
attribute {
fn:data (([Expr1]Expr)) } {
fs:item-sequence-to-string
(([Expr2]Expr)) } |
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 |- attribute QName {
Expr } : attribute QName of type xs:untypedAtomic |
|
|||||
|
|||||
statEnv |- attribute {
Expr1 } {
Expr2 } : attribute * of type
xs:untypedAtomic |
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 content expression is evaluated in the dynamic environment.
|
||
|
||
dynEnv |- attribute QName {
Expr } => attribute QName of type
xs:untypedAtomic {
AtomicValue } |
|
|||||
|
|||||
dynEnv |- attribute {
Expr1 } {
Expr2 } => attribute
QName1 of type xs:untypedAtomic { AtomicValue2 } |
[110 (XQuery)] | CompDocConstructorXQ |
::= | "document" "{" Expr
"}" |
Core Grammar
The Core grammar production for a computed document constructor is:
[66 (Core)] | CompDocConstructor |
::= | "document" "{" Expr
"}" |
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 fs:item-sequence-to-node-sequence
implements most of this conversion.
[document { Expr }]Expr |
== |
document { fs:item-sequence-to-node-sequence
(([Expr]Expr)) } |
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 |- document { Expr } : document { Type } |
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.
[114 (XQuery)] | CompTextConstructorXQ |
::= | "text" "{" Expr
"}" |
Core Grammar
The Core grammar production for a computed text constructor is:
[71 (Core)] | CompTextConstructor |
::= | "text" "{" Expr
"}" |
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, the fs:item-sequence-to-untypedAtomic-text
function implements this conversion.
[text { Expr }]Expr |
== |
text { (fs:item-sequence-to-untypedAtomic-text (fn:data (([Expr]Expr)))) cast
as xs:string ? } |
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.
If the argument expression returns the empty sequence, the text node constructor returns the empty sequence.
If the argument expression returns a value of type
xs:string
, the text node constructor returns a text
node with that string as content.
[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? "}" |
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 }]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)) } |
The static typing rules for processing-instruction constructors are straightforward.
statEnv |- Expr : xs:untypedAtomic |
|
statEnv |- processing-instruction NCName { Expr } : processing-instruction NCName |
statEnv |-
Expr1 :
(xs:NCName | xs:string | xs:untypedAtomic )
statEnv |-
Expr2 : xs:untypedAtomic |
|
statEnv |- processing-instruction { Expr1 } { Expr2 } : processing-instruction * |
The dynamic evaluation rules for computed processing-instructions are straightforward.
[115 (XQuery)] | CompCommentConstructorXQ |
::= | "comment" "{" Expr
"}" |
Core Grammar
The Core grammar production for computed comment constructors is:
[72 (Core)] | CompCommentConstructor |
::= | "comment" "{" Expr
"}" |
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 } |
The static typing rule for computed comment constructors is straightforward.
The dynamic evaluation rule for computed comment constructors is straightforward.
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].
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.
[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:
[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)? |
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 |
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.
[
|
||||
== | ||||
|
Likewise, a LetClause clause is normalized to nested let expressions, each of which binds one variable:
[
|
||||
== | ||||
|
A WhereClause is normalized to an IfExpr, with the else-branch returning the empty sequence:
[ where Expr1 FormalReturnClause]Expr |
== |
if ( fn:boolean(( [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.
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>)
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 |- 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 |- 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 |- 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 |- 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.
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 |- 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 |- 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 |- 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 |- 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>)
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 |- 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 |- let $VarName1 as SequenceType := Expr1 return Expr2 : Type2 |
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 |- 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 |- 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
.
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.
Although an OrderByClause does not affect the type of a
FLWORExpr expression, it must still undergo static
analysis, in case this raises a static error. 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.
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 | ||||||
== | ||||||
|
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
"}" |
OrderedExpr (resp. UnorderedExpr) expressions are normalized to OrderedExpr (resp. UnorderedExpr) expressions in the [XPath/XQuery] Core.
OrderedExpr and UnorderedExpr expressions set
the ordering mode in the static context to ordered
or
unordered
.
|
|||
|
|||
statEnv |- ordered { Expr } : Type |
|
|||
|
|||
statEnv |- unordered { Expr } : Type |
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.
Introduction
A conditional expression supports conditional evaluation of one of two expressions.
[45 (XQuery)] | IfExprXQ |
::= | "if" "(" Expr ")" "then"
ExprSingle "else" ExprSingle |
Core Grammar
The Core grammar production for the conditional expression is:
[35 (Core)] | IfExpr |
::= | "if" "(" Expr ")" "then"
ExprSingle "else" ExprSingle |
Conditional expressions are normalized as follows.
[if (Expr1) then Expr2 else Expr3]Expr | |
== | |
|
statEnv |- Expr1 : xs:boolean
statEnv |- Expr2 : Type2
statEnv |- Expr3 : Type3 |
|
statEnv |- if
(Expr1) then
Expr2 else
Expr3 : (Type2
| Type3) |
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.
Introduction
[XPath/XQuery] defines two quantification expressions:
[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 |
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 | |||||
== | |||||
|
[every $VarName1 in Expr1, ..., $VarNamen in Exprn satisfies Expr]Expr | |||||
== | |||||
|
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 |- some
$VarName1 in
Expr1 satisfies
Expr2 :
xs:boolean |
The next rule is for SomeExpr with the optional type declaration.
|
||||||
|
||||||
statEnv |- some
$VarName1 as
SequenceType in Expr1 satisfies Expr2 : xs:boolean |
The next rule is for EveryExpr without the optional type declaration.
|
||||
|
||||
statEnv |- every
$VarName1 in
Expr1 satisfies
Expr2 :
xs:boolean |
The next rule is for EveryExpr with the optional type declaration.
|
||||||
|
||||||
statEnv |- every
$VarName1 as
SequenceType in Expr1 satisfies Expr2 : xs:boolean |
If its input expression returns the empty sequence, the SomeExpr expression returns 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 |- 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 |- 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 |- 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 |- some $VarName1 as SequenceType in Expr1 satisfies Expr2 => false |
If its input expression returns the empty sequence, the EveryExpr expression returns 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 |- 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 |- 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 |- 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 |- every $VarName1 as SequenceType in Expr1 satisfies Expr2 => true |
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].
[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.
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.
[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 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.
[ case $VarName as SequenceType return Expr ]Case |
== |
case $VarName as SequenceType return [ Expr ]Expr |
[
|
|||||
== | |||||
|
Notation
For convenience, we use the following auxiliary grammar productions to denote case clauses in a typeswitch.
[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
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
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.
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 |-
|
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.
|
||||
|
||||
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 |- Type0 case default $VarName return Expr : Type |
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 |- 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.
|
|||||
|
|||||
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 clauses are evaluated in order by applying the inference rule recursively.
|
||
|
||
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.
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
"?"? |
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 | ||
== | ||
|
[Expr cast as AtomicType? ]Expr | ||||
== | ||||
|
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
holds if AtomicValue1 can be cast to type AtomicType, resulting in the new value AtomicValue2 according to the rules in Section 17 CastingFO.
|
|||
|
|||
dynEnv |- Expr cast as AtomicType => AtomicValue2 |
[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 )? |
The normalization of castable simply maps its expression argument.
The type of a Core castable
expression is always a
boolean.
|
statEnv |- Expr castable as
AtomicType :
xs:boolean |
Notation
The auxiliary judgment:
holds when Value can be atomized and cast to SingleType. Its definition depends on the cast value to type judgment.
|
|||
|
|||
|
If the value of the operand expression can be cast to the given
type, then the castable
expression evaluates to
true.
|
|||
|
|||
|
Otherwise, 'castable as' evaluates to false.
Constructor functions provide an alternative syntax for casting.
Notation
Calls to constructor functions are normalized differently from other function calls, so we introduce an auxiliary judgment to detect whether the function being called is a constructor function.
This judgment holds when the expanded function name maps to an atomic type in the in-scope schema types.
|
||
|
||
statEnv |- expanded-QName denotes a constructor function |
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 confirm that it denotes a constructor function in the
static context.
|
|||
|
|||
statEnv |- [QName(ExprSingle1)]Expr = [ExprSingle1 cast as QName?]Expr |
[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.
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.
[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.
A validate expression with no validation mode is normalized into a validate expression with the validation mode set to strict.
Static typing of the validate operation begins with the following rule. We infer the type of the argument expression, and ensure that it is consistent with a run-time argument that is either an element or a well-formed document node (i.e., with only one root element and no text nodes). Then we hand off the type and the validation mode to the validate judgment.
|
||||
|
||||
|
Because the type of the argument expression may be a union of multiple element and document types, the judgment:
extracts the prime type of the argument type, applies the validate item type judgment to each type in the union, and yields the union of the results.
|
||||||
|
||||||
|
The judgement
does a case analysis on the different item types that it can encounter.
|
|||
|
|||
|
|
|||
|
|||
|
|
||
|
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 [XSLT 2.0 and XQuery 1.0 Serialization (Second Edition)], 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 [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)].
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.
|
||||||
|
||||||
dynEnv |- validate ValidationMode { Expr } => ElementValue3 |
The rule for validating a document node is similar to that for validating an element node.
|
||||||
|
||||||
dynEnv |- validate ValidationMode { Expr } => document { ElementValue3 } |
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*)) |
Extension expressions are normalized as extension expressions in the [XPath/XQuery] Core.
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 () } |
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 |- Pragma+ { Expr } : Type2 |
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 |- Pragma+ { Expr } => Value |
If none of the pragmas is recognized, the dynamic semantics of an ExtensionExpr are the same as evaluating the given expression.
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.
[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:
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 (Second Edition)] 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.
[71 (Formal)] | PrologDeclList |
::= | (PrologDecl Separator PrologDeclList)? |
[72 (Formal)] | PrologDecl |
::= | DefaultCollationDecl |
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:
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:
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:
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.
If the case of a namespace declaration, the static context is extended with the corresponding namespace binding.
|
||||
|
||||
statEnv |- PrologDecl ; PrologDeclList =>sigs statEnv2 |
If the case of a function declaration, the static context is extended with the corresponding signature.
|
||||
|
||||
statEnv |- PrologDecl ; PrologDeclList =>sigs statEnv2 |
|
|||||||||
|
|||||||||
statEnv |- FunctionDecl =>sigs statEnv1 |
For all other kinds of declarations, the static context is left unchanged.
|
||
|
||
statEnv |- PrologDecl ; PrologDeclList =>sigs statEnv |
In case of a function declaration, the static context is extended with the corresponding function signature.
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.
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]).
|
|||||
|
|||||
AnyURI ; statEnv |- PrologDecl ; PrologDeclList =>stat statEnv2 with PrologDecl1 ; PrologDeclList1 |
|
|||||
|
|||||
AnyURI ; statEnv |- PrologDecl ; PrologDeclList =>stat statEnv2 with PrologDecl1 ; PrologDeclList1 |
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.
|
||||
|
||||
PrologDeclList QueryBody : Type |
Notation
Similarly, the judgment:
holds if under the dynamic environment dynEnv1, the sequence of prolog declarations PrologDeclList yields the dynamic environment dynEnv2.
The judgment:
holds if under the dynamic environment dynEnv, the single prolog declaration PrologDecl yields the new dynamic environment dynEnv1.
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.
The second rule simply computes the dynamic environment by processing the prolog declarations in order.
|
|||
|
|||
dynEnv |- PrologDecl ; PrologDeclList =>dyn dynEnv2 |
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.
|
|||||
|
|||||
|
Notation
We define a new judgment that maps a module's target namespace (or a main module) to the corresponding module's static environment:
We also define a new judgment that maps a module's target namespace (or a main module) to the corresponding module's dynamic environment:
For a main module, those judgments are defined as follows.
|
||
|
||
|
|
||
|
||
|
For a library module, those judgments are defined in [5.11 Module Import].
[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.
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 |
::= | ";" |
Module declarations are left unchanged through normalization.
[ModuleDecl]PrologDecl |
== |
ModuleDecl |
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.
|
||||||||||
|
||||||||||
|
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.
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.
|
|||||||||
|
|||||||||
|
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.
[11 (XQuery)] | BoundarySpaceDeclXQ |
::= | "declare" "boundary-space" ("preserve" |
"strip") |
The semantics of a boundary-space declaration is not specified formally.
[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 |
Default collation declarations are left unchanged through normalization.
[DefaultCollationDecl]PrologDecl |
== |
DefaultCollationDecl |
The default collation declaration updates the collations environment component within the static environment. The collations environment component is used by several functions in [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)], but is not used in the Formal Semantics.
|
||||
|
||||
|
The default collation declaration does not affect the dynamic context.
[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 |
Base URI declarations are left unchanged through normalization.
[BaseURIDecl]PrologDecl |
== |
BaseURIDecl |
A base URI declaration specifies the base URI property of the static context, which is used when resolving relative URIs within a module.
|
|||
|
|||
|
The base URI declaration does not affect the dynamic context.
[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.
[89 (Formal)] | ConstructionMode |
::= | "preserve" | "strip" |
Construction declarations are left unchanged through normalization.
[ConstructionDecl]PrologDecl |
== |
ConstructionDecl |
The construction declaration modifies the construction mode in the static context.
statEnv1 = statEnv + constructionMode( ConstructionMode) | ||
|
||
|
The construction declaration does not have any effect on the dynamic context.
[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") |
Ordering mode declarations are left unchanged through normalization.
[OrderingModeDecl]PrologDecl |
== |
OrderingModeDecl |
The ordering mode declaration does not have any effect on the static context.
The ordering mode declaration does not have any effect on the dynamic context.
[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") |
Empty order declarations are left unchanged through normalization.
[EmptyOrderDecl]PrologDecl |
== |
EmptyOrderDecl |
The empty order declaration does not have any effect on the static context.
The empty order declaration does not have any effect on the dynamic context.
[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" |
Copy-namespace declarations are left unchanged through normalization.
[CopyNamespacesDecl]PrologDecl |
== |
CopyNamespacesDecl |
The copy-namespace declaration does not have any effect on the static context.
The copy-namespace declaration does not have any effect on the dynamic context.
[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:
[13 (Core)] | SchemaImport |
::= | "import" "schema" SchemaPrefix? URILiteral ("at" URILiteral ("," URILiteral)*)? |
[14 (Core)] | SchemaPrefix |
::= | ("namespace" NCName "=")
| ("default" "element" "namespace") |
Schema imports are left unchanged through normalization.
[SchemaImport]PrologDecl |
== |
SchemaImport |
Notation
For convenience, we introduce the following auxiliary grammar productions.
[16 (Formal)] | LocationHints |
::= | "at" URILiteral (","
URILiteral)* |
[82 (Formal)] | OptLocationHints |
::= | LocationHints? |
Notation
The following auxiliary judgments are used when processing schema imports.
The judgment:
holds if under the static environment statEnv1, the sequence of type definitions Definitions yields the new static environment statEnv2.
The judgment:
holds if under the static environment statEnv1, the single definition Definition yields the new static environment statEnv2.
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.
|
|||
|
|||
|
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.
|
|||||
|
|||||
|
|
|||||
|
|||||
|
An empty sequence of type definitions yields the input environment.
Each type definition is added into the static environment.
|
|||
|
|||
|
Each type, element, or attribute declaration is added respectively to the type, element and attribute declarations components of the static environment.
|
|||
|
|||
|
|
|||
|
|||
|
|
|||
|
|||
|
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.
The schema import declarations do not affect the dynamic context.
[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:
[15 (Core)] | ModuleImport |
::= | "import" "module" ("namespace" NCName "=")? URILiteral ("at" URILiteral ("," URILiteral)*)? |
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
(FunctionKey, FunctionSig) pairs 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
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.
|
|||||
|
|||||
|
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.
|
||
|
|
|||
|
|||
|
The following rules add each function explicitly declared in the imported module to the importing module's dynamic function environment.
|
||
|
|
|||
|
|||
|
Notation
The following auxiliary judgments is used to extend a given dynamic environment with the dynamic environment from an imported module.
The judgment
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.
|
||||
|
||||
|
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.
|
||||
|
||||
|
|
||||||
|
||||||
|
|
||||
|
||||
|
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.
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.
|
||||||||
|
||||||||
|
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.
[10 (XQuery)] | NamespaceDeclXQ |
::= | "declare" "namespace" NCName "=" URILiteral |
Core Grammar
The core grammar production for namespace declarations is:
[3 (Core)] | NamespaceDecl |
::= | "declare" "namespace" NCName "=" URILiteral |
Namespace declarations are left unchanged through normalization.
[NamespaceDecl]PrologDecl |
== |
NamespaceDecl |
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.
|
|||
|
|||
|
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.
|
||
|
||
|
The namespace declaration does not affect the dynamic context.
[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 |
Default namespace declarations are left unchanged through normalization.
[DefaultNamespaceDecl]PrologDecl |
== |
DefaultNamespaceDecl |
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) | ||
|
||
|
|
||||
|
||||
|
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) | ||
|
||
|
|
||||
|
||||
|
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.
Default namespace declarations do not affect the dynamic context.
[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 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 |
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.
|
||||
|
||||
|
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.
|
||||||
|
||||||
|
If the variable declaration is external and has a type declaration, the static type of the variable is the specified type.
|
||||
|
||||
|
To evaluate a variable declaration, its associated expression is evaluated, and the dynamic context is updated with the variable bound to the resulting value.
|
||||
|
||||
|
|
||||||
|
||||||
|
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).
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.
[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:
[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.
The parameter list and body of a user-defined function are all normalized into Core expressions.
|
|||
|
|||
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:
holds if the function declaration FunctionDecl with the signature FunctionSig has the type Type.
Static context processing accesses the function signature from the static context, and checks that the function declaration corresponds to the declared type.
|
|||
|
|||
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.
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 |- function declaration declare function QName () as SequenceTyper { Expr } with signature declare function expanded-QName() as Typer : 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 |- 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 |
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.
|
|||
|
|||
dynEnv |- declare function QName () as SequenceTyper { Expr } =>dyn dynEnv1 |
|
||||||
|
||||||
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].
[13 (XQuery)] | OptionDeclXQ |
::= | "declare" "option" QName
StringLiteral |
Core Grammar
The core grammar production for option declarations is:
[5 (Core)] | OptionDecl |
::= | "declare" "option" QName
StringLiteral |
Option declarations are left unchanged through normalization.
[OptionDecl]PrologDecl |
== |
OptionDecl |
An option declaration does not have any effect on the static context.
An option declaration does not have any effect on the dynamic context.
The XQuery Formal Semantics is intended primarily as a component that can be used by [XQuery 1.0: An XML Query Language (Second Edition)], or a host language of [XML Path Language (XPath) 2.0 (Second Edition)]. 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.
This specification normatively defines the static typing feature which can be used in [XQuery 1.0: An XML Query Language (Second Edition)] or a host language of [XML Path Language (XPath) 2.0 (Second Edition)]. The static typing feature is specified using the static typing judgment introduced in [3.2.3 Static typing judgment].
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.
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.
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 [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)].
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:
FN-URI
for functions from the [XQuery 1.0 and XPath 2.0 Functions and
Operators (Second Edition)] document.
OP-URI
for operators from the [XQuery 1.0 and XPath 2.0 Functions and
Operators (Second Edition)] document.
FS-URI
for formal semantics functions.
Introduction
This section gives the definition and semantics of functions that are used in the formal semantics but are not in [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)]. Their dynamic semantics are defined in the same informal style as in the [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)] document. The static semantics of some formal-semantics functions require custom static typing rules.
convert-operand
functionfs: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:
If $actual
is the empty sequence, returns the empty
sequence.
If $actual
is an instance of type xs:untypedAtomic
, then
if $expected
is an instance of type xs:untypedAtomic
or
xs:string
, returns $actual
cast to
xs:string
;
if $expected
is of numeric type, returns
$actual
cast to xs:double
otherwise returns $actual
cast to the type of
$expected
.
Otherwise, returns $actual
.
To analyze a call to fs:convert-operand
,
we extract the prime type of the static type of each of the two
arguments. (Each prime type will be a union of atomic types.) We
consider all possible pairs formed by taking one atomic type from
each prime type, apply the convert_operand judgment to each pair, form
the union of the results, and adjust that by the quantifier of the
first argument's type.
|
|||||||||||||
|
|||||||||||||
|
The auxiliary judgment:
is the static analog of the fs:convert-operand
function. It is defined by the following rules.
No conversion is needed if the first argument isn't an instance
of type xs:untypedAtomic
.
|
||
|
||
|
The remaining rules cover the cases when the first argument
is an instance of type xs:untypedAtomic
. The
outcome depends on the type of the second argument.
If the second argument is of type xs:untypedAtomic
or
xs:string
, the first is converted to a string.
|
|||
|
|||
|
If the second argument is numeric, the first is converted to
xs:double
.
|
|||
|
|||
|
Otherwise, the first argument is converted to the type of the second argument.
|
|||
|
|||
|
convert-simple-operand
functionfs:convert-simple-operand
($actual
as
xs:anyAtomicType
*
, $expected
as
xs:anyAtomicType
) as
xs:anyAtomicType *
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.
The following static typing rules correspond to the dynamic semantics rules given above.
|
|||
|
|||
statEnv |- (FS-URI ,"convert-simple-operand ")(Type1,
Type2) : Type3
· quantifier(Type1) |
distinct-doc-order
functionfs: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.
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].
distinct-doc-order-or-atomic-sequence
functionfs: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.
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].
|
||
|
||
|
item-sequence-to-node-sequence
functionfs: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 1e
and 2
in
Section 3.7.1.3
ContentXQ (with the value bound to
$items
playing the role of "the value of an enclosed
expression").
If the input sequence contains any attribute nodes, they must precede any other items.
|
||
|
||
|
|
||
|
||
|
|
||
|
||
|
item-sequence-to-string
functionIntroduction
fs:item-sequence-to-string
($items
as
item()*
) as
xs:string
The fs:item-sequence-to-string
function converts a sequence of item values to a string by applying
the normative rules in Section
3.7.3.2 Computed Attribute
ConstructorsXQ for processing the
content expression.
If the input of the fs:item-sequence-to-string
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.
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.
item-sequence-to-untypedAtomic-PI
functionIntroduction
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.
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.
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.
item-sequence-to-untypedAtomic-text
functionIntroduction
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.
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.
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.
item-sequence-to-untypedAtomic-comment
functionIntroduction
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.
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.
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.
apply-ordering-mode
functionfs:apply-ordering-mode
($items
as
item()*
) as
item()*
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 |
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) |
to
functionfs: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.
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) };
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.
node-sequence
functionfs:node-sequence
($nodes
as
node()*
) as
node()*
If the input is a (possibly empty) sequence of nodes, fs:node-sequence
simply returns that sequence. Otherwise, it raises a type
error.
The static type of a call to fs:node-sequence
is
that of its argument, as long as that type is a subtype of
node()*
.
statEnv |- Type <: [node()*]sequencetype |
|
statEnv |- (FS-URI ,"node-sequence ")(Type)
: Type |
item-at
functionfs:item-at
($sourceSeq
as
item()*
,
$loc
as
xs:double
) as
item()?
The fs:item-at
function returns the item at a specified position in a
sequence.
If $loc
is numeric-equal to the position of some
item in $sourceSeq
, that item is returned. (This
implies that $sourceSeq
is non-empty, and
$loc
is numeric-equal to an integer between 1 and
n
inclusive, where n
is the number of
items in $sourceSeq
.)
Otherwise, the empty sequence is returned.
The function is roughly equivalent to the following user-defined function.
declare function fs:item-at( $sourceSeq as item()*, $loc as xs:double) as item()? { if ($loc mod 1 eq 0) then fn:subsequence($sourceSeq,$loc,1) else () };
The static typing rules for invocations of fs:item-at
depend on the
syntactic form of the second argument. If it is the IntegerLiteral
1, then we can be relatively precise about the resulting type.
|
||||
|
||||
|
Otherwise, the following less precise rule is used.
|
|||
|
|||
|
(Since invocations of fs:item-at
arise only as
the result of particular normalization rules, Expr2 in the
above rule must be either $fs:last
,
$fs:position
, or a NumericLiteral. Thus, there is no
need to check its type.)
Introduction
This section gives special normalization and static typing rules for functions in [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)] 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.
fn:last
context functionAs 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.
fn:position
context functionAs explained in [3.1.2 Dynamic
Context], the fn:position()
context function
is modeled using the Formal Semantics variable $
fs:position
.
For that function the following static typing and dynamic
evaluation rules apply.
fn:abs
, fn:ceiling
,
fn:floor
, fn:round
, and
fn:round-half-to-even
functionsNotation
The auxiliary judgment has base atomic type is used in the next subsection and also in [7.2.10 The fn:min, fn:max, fn:avg, and fn:sum functions].
To a first approximation, this judgment holds when AtomicTypeName1
is (or is derived from) primitive atomic type AtomicTypeName2.
However, for the purpose of typing the functions that use this
judgment, there are three non-primitive atomic types that are
treated similarly to primitive types: xs:integer
(derived from xs:decimal
), and xs:yearMonthDuration
and
xs:dayTimeDuration
(derived from xs:duration
).
If AtomicTypeName1
is (or is a subtype of) any primitive atomic type other than
xs:decimal
or xs:duration
, then that type
is its base atomic type.
|
||||
|
||||
|
Similarly for xs:integer
, xs:yearMonthDuration
, and
xs:dayTimeDuration
.
|
|||
|
|||
|
For xs:decimal
, we exclude xs:integer
and its subtypes:
|
|||
|
|||
|
And finally, for xs:duration
, we exclude xs:yearMonthDuration
and
xs:dayTimeDuration
,
and their subtypes.
|
||||
|
||||
|
Note that, in the declarations for the built-in functions
fn:abs
, fn:ceiling
,
fn:floor
, fn:round
, and
fn:round-half-to-even
, the (first) parameter is
declared with type "numeric?
". Thus, for a call to one
of these functions, the normalization rules of [4.1.5 Function Calls] will have
wrapped the argument in calls to fn:data
() and
fs:convert-simple-operand
()
(with a 'prototypical value' of type xs:double
). Thus,
static analysis of the call is guaranteed that the argument type is
a subtype of xs:anyAtomicType
*, with no
occurrences of xs:untypedAtomic
.
In the static typing rule for these functions, we check that the argument type is numeric, extract its prime type (which must be a choice of atomic types), find the base atomic type for each, and then form the choice of those results.
|
||||||||
|
||||||||
|
The fn:round-half-to-even
function also has a
two-parameter version. Its static type-checking can be reduced to
that of the one-parameter version.
fn:boolean
and fn:not
functionsThe fn:boolean
function as described in the
[XQuery 1.0 and XPath 2.0 Functions and
Operators (Second Edition)] document takes an empty sequence, a
sequence whose first item is a node, or a singleton value of type
xs:boolean
, xs:string
,
xs:anyURI
, xs:untypedAtomic
or some
numeric type. All other values are illegal. The static typing of
fn:boolean
reflects these restrictions, but further
constrains "a sequence whose first item is a node" to "a sequence
of nodes".
The fn:not
function has an implicit call to
fn:boolean
, and raises type errors for the same cases,
so its static typing is the same as fn:boolean
.
|
|||
|
|||
statEnv
|- expanded-QName(Type) : xs:boolean |
fn:collection
and fn:doc
functionsIntroduction
The static typing rules for fn:collection
and
fn:doc
depend on the syntactic form of their input
expression. As a result, the corresponding static typing rules must
be written directly over the input expression, unlike the other
functions in this section.
The fn:collection
function as described in the
[XQuery 1.0 and XPath 2.0 Functions and
Operators (Second Edition)] document, takes a string-valued
expression, which denotes a URI, and returns a value.
If the fn:collection
function has no parameter, the
result type is given by the implementation for the default sequence
if it exists.
|
|||
|
|||
statEnv |- QName() : Type |
If the argument to fn:collection
is a
URILiteral expression which is defined in statEnv.collectionType, then the
result type is the type corresponding to the URILiteral in
statEnv.collectionType.
|
|||
|
|||
statEnv |- QName(URILiteral) : Type |
Otherwise, if the argument is a URI literal but is not defined in statEnv.collectionType, or if it is not a URI literal, then we don't know anything about the URI and the static type is a collection of nodes.
|
|||
|
|||
statEnv |- QName(URILiteral) : (element * | attribute * | processing-instruction * | text | comment | document ) * |
|
|||
|
|||
statEnv |- QName(Expr) : (element * | attribute * | processing-instruction * | text | comment | document ) * |
The fn:doc
function has similar static typing
rules, but, in addition, the static type must be a document
node.
|
||||
|
||||
statEnv |- QName(URILiteral) : Type |
Otherwise, if the argument is a URI literal not defined in the domain of statEnv.docType or if it is not a URI literal, then we don't know anything about the URI, and the static type is document.
|
|||
|
|||
statEnv |- QName(URILiteral) : document? |
|
|||
|
|||
statEnv |- QName(Expr) : document? |
fn:data
functionIntroduction
The fn:data
function converts a sequence of items
to a sequence of atomic values.
Notation
Inferring the type for the fn:data
function is done by applying the data on auxiliary judgment, using the same
approach as for the XPath steps.
The general rule for fn:data
is to apply the filter
data on to the prime
type of its argument type, then apply the quantifier to the
result:
When applied to none, data on yields none.
When applied to empty, data on yields empty.
When applied to the union of two types, data on is applied to each of the two types. The resulting type is computed using prime and quantifier, which are defined in [8.4 Judgments for FLWOR and other expressions on sequences]. This rule is necessary because data on may return a sequence of atomic types.
|
|||
|
|||
statEnv |- data on (Type1|Type2) : prime(Type1'|Type2') · quantifier(Type1'|Type2') |
When applied to an atomic type, data on simply returns the atomic type:
When applied to comment or processing instruction node types,
data on returns
xs:string
When applied to text or document node types, data on returns xs:untypedAtomic
When applied to element node types with type
annotationXQ xs:untyped
, the data on filter returns
xs:untypedAtomic
.
|
||
|
||
statEnv |- data on ElementType : xs:untypedAtomic |
When applied to an attribute node type, the data on filter returns the attribute's simple type.
|
|||
|
|||
statEnv |- data on AttributeType : Type |
When applied to an element type whose type annotationXQ denotes a simple type or a complex type of simple content, data on returns the element's simple type.
|
||||
|
||||
statEnv |- data on ElementType : Type1 |
For any element node whose type
annotationXQ is a complex type with
element-only content, the typed-value is undefined, and applying
fn:data
to such a node raises a type error.
Consequently, the data
on judgment is not defined on any element type whose
type
annotationXQ denotes a complex type
of element-only content. Attempting to apply data on to such a type raises a type
error.
Because we can derive complex types with element-only
content from complex types with mixed content (including
xs:anyType
), the data on judgment is also not defined on any
element type whose type
annotationXQ is a complex type of
mixed content (other than xs:untyped
, which is handled
above). Attempting to satisfy the data on judgment for such a type will fail,
and the processor will raise a type error.
Example
Consider the following variable and its corresponding static type.
$x : (element price { attribute currency { xs:string }, xs:decimal } | element price_code { xs:integer })
Applying the fn:data
function on that variable
results in the following type.
fn:data($x) : (xs:decimal | xs:integer)
Because the input type is a choice, applying the data on filter results in a
choice of simple types for the output of the fn:data
function.
fn:distinct-values
functionThe fn:distinct-values
function expects a sequence
of atomic values as input and returns a sequence of prime types,
which are defined in [8.4 Judgments for
FLWOR and other expressions on sequences].
fn:unordered
functionThe static semantics for fn:unordered
is computed
using prime and quantifier, which are defined
in [8.4 Judgments for FLWOR and other
expressions on sequences]. The type of the argument is
determined, and then prime(.) and quantifier(.) are applied to that type.
fn:error
functionThe fn:error function always has the none
type.
fn:min
, fn:max
,
fn:avg
, and fn:sum
functionsIntroduction
The semantics of aggregate functions convert any item of type
xs:untypedAtomic
in
the input sequence to xs:double
, then attempt to
promote all values in the input sequence to values that are
comparable. The static typing rules reflect the dynamic evaluation
rules.
The fn:sum
function has two forms. The first form
takes two arguments: The first argument is the input sequence and
the second argument is the value that should be returned if the
input sequence is empty. In case there is no second argument, the
value returned for an empty sequence is the xs:integer
value 0. The following static typing rule applies in the case there
is no second argument.
Notation
The type function convert_untypedAtomic takes a prime type and
converts all occurrences of the type xs:untypedAtomic
to a
target type. It is defined recursively as follows.
convert_untypedAtomic(xs:untypedAtomic , Type) |
= | Type | |
if not(FormalItemType = xs:untypedAtomic ) |
convert_untypedAtomic(FormalItemType, Type) | = | FormalItemType |
convert_untypedAtomic(empty ,
Type) |
= | empty |
|
convert_untypedAtomic(none ,
Type) |
= | none |
|
convert_untypedAtomic(Type1 | Type2, Type) | = | convert_untypedAtomic(Type1, Type) | convert_untypedAtomic(Type2, Type) |
Notation
The function aggregate_quantifier converts the input type quantifier zero-or-more or zero-or-one to the result type quantifier zero-or-one, and converts the input type quantifier one or one-or-more, to the result type quantifier one.
aggregate_quantifier(? ) |
= | ? |
aggregate_quantifier(* ) |
= | ? |
aggregate_quantifier(1 ) |
= | 1 |
aggregate_quantifier(+ ) |
= | 1 |
Now we can define the static typing rules for the aggregate
functions. Note that the normalization rules of [4.1.5 Function Calls] will have
wrapped each argument in calls to fn:data
() and
fs:convert-simple-operand
()
(with a 'prototypical value' of type xs:double
). Thus,
static analysis of the call to an aggregate function is guaranteed
that any argument type is a subtype of xs:anyAtomicType
*, with no
occurrences of xs:untypedAtomic
.
First, we can quickly deal with fn:avg
. For the
purposes of static type analysis, fn:avg($arg)
is
equivalent to fs:div( fn:sum($arg,()), fn:count($arg)
)
Thus, we have the rule:
|
|||
|
|||
|
For the remaining aggregate functions (fn:min
,
fn:max
, and fn:sum
), the general approach
is as follows. First, we check that the input type(s) are
acceptable for the function. Then we construct the (first)
argument's prime type, a union of AtomicTypeNames. For each of the
latter, we find the 'base atomic type'. The union of these base
atomic types is the basis for the result type, which may finally be
adjusted for cardinality (fn:min
and
fn:max
) or for the effect of the second argument
(fn:sum
). In addition, we provide a rule for the
special case when the (first) argument has type 'empty'.
For fn:min
and fn:max
, the permitted
input types are all those for which ge(T,T) and le(T,T) are
defined. An empty input sequence yields an empty result.
|
|||
|
|||
|
|
|||||||||
|
|||||||||
|
For fn:sum
, the permitted input types for the first
argument are all those for which plus(T,T) is defined. If you pass
an empty sequence as the first argument, the function returns the
value of the second argument.
|
||||||||||
|
||||||||||
|
The second argument's contribution (if any) to the above result type is determined as follows. If the first argument could be the empty sequence, we add the type of the second argument to the result type. Otherwise, the type of the second argument is ignored.
fn:remove
functionThe static type for the fn:remove
function is
computed using prime and
quantifier, which are
defined in [8.4 Judgments for FLWOR and
other expressions on sequences]. Since one item may be
removed from the sequence, the resulting type is made optional.
fn:reverse
functionThe static type for the fn:reverse
function is
computed using prime and
quantifier, which are
defined in [8.4 Judgments for FLWOR and
other expressions on sequences].
fn:subsequence
functionThe static type of a call to fn:subsequence
is
computed using prime() and
quantifier(), which
are defined in [8.4 Judgments for FLWOR
and other expressions on sequences].
op:union
, op:intersect
, and
op:except
operatorsThe static semantics for op:union
is computed using
prime and quantifier, which are defined
in [8.4 Judgments for FLWOR and other
expressions on sequences]. The type of each argument is
determined, and then prime(.) and quantifier(.) are applied to the sequence type
(Type1, Type2).
The static semantics of op:intersect
is analogous
to that for op:union
. Because an intersection may be
empty, the result type is optional.
The static semantics of op:except
follows. The type
of the second argument is ignored as it does not contribute to the
result type. As with op:intersect
, the result of
op:except
may be the empty sequence.
fn:insert-before
functionThe static type for the fn:insert-before
function
is computed using prime
and quantifier, which
are defined in [8.4 Judgments for FLWOR
and other expressions on sequences].
fn:zero-or-one
, fn:one-or-more
, and
fn:exactly-one
functionsThe functions fn:zero-or-one
,
fn:one-or-more
, and fn:exactly-one
check
that the cardinality of a sequence is in the expected range. They
are useful to override the static type inferred for a given
query.
For example, in the following query, the user may know that all ISBN numbers are unique and therefore that the function always returns at most one book element. However, the static typing feature cannot infer a precise enough type and will raise a type error during static type analysis.
declare function book_with_isbn($isbn as xs:string) as schema-element(book)? { //book[@isbn=$isbn] }
In that query, the fn:zero-or-one
function can be
used to tell the type system that the cardinality is known to be
zero or one.
declare function book_with_isbn($isbn as xs:string) as schema-element(book)? { fn:zero-or-one(//book[@isbn=$isbn]) }
The static typing rules for those functions always infer a type with the cardinality indicated by that function.
This section defines auxiliary judgments used in defining the formal semantics. Many auxiliary judgments are used in both static typing and dynamic evaluation rules. Those auxiliary judgments that are used in only the static or dynamic semantics are labeled as such.
Introduction
This section defines several auxiliary judgments to access components of the [XPath/XQuery] type system. The first two judgments (derives from and substitutes for) are used to access the type and element name hierarchies in an XML Schema. The other judgments (name lookup, type lookup, extended by, adjusts to and expands to) are used to lookup the meaning of element or attribute types from the schema. These judgments are used in many expressions, notably in the specification of type matching (See [8.3 Judgments for type matching]), validation (See [F.1 Judgments for the validate expression]), and the static semantics of step expressions (See [8.2 Judgments for step expressions and filtering]).
Notation
The judgment
holds when TypeName1 derives from TypeName2. This judgment formalizes the definition of the
derives-from
function in Section
2.5.4 SequenceType MatchingXQ.
Example
For example, assuming the extended XML Schema given in section [2.4.5 Example of a complete Schema], then the following judgments hold.
USAddress derives from xs:anyType NYCAddress derives from USAddress NYCAddress derives from xs:anyType xsd:positiveInteger derives from xsd:integer xsd:integer derives from xs:anySimpleType fs:anon3 derives from xsd:positiveInteger fs:anon3 derives from xsd:integer fs:anon3 derives from xs:anySimpleType fs:anon3 derives from xs:anyType
Note
Derivation is a partial order. It is reflexive and transitive by the definition below.
Semantics
This judgment is specified by the following rules.
Every type name derives from itself.
Every type name derives from the type it is declared to derive from by extension or restriction.
|
|||
|
|||
statEnv |- TypeName derives from BaseTypeName |
|
|||
|
|||
statEnv |- TypeName derives from BaseTypeName |
The above rules all require that the type names be defined in the static context, but [XPath/XQuery] permits references to "unknown" type names, i.e., type names that are not defined in the static context. An unknown type name might be encountered, if a module in which the given type name occurs does not import the schema in which the given type name is defined. In this case, an implementation is allowed (but is not required) to provide an implementation-dependent mechanism for determining whether the unknown type name is the same as or derived by restriction from the expected type name. The following rule formalizes this implementation dependent mechanism.
|
||
|
||
statEnv |- TypeName1 derives from TypeName2 |
The derivation relation is transitive.
The substitutes judgment is used to know whether an element name is in the substitution group of another element name.
Notation
The judgment
holds when ElementName1 substitutes for ElementName2.
Example
For example, assuming the extended XML Schema given in section [2.4.5 Example of a complete Schema], then the following judgments hold.
usaddress substitutes for address nyaddress substitutes for usaddress nyaddress substitutes for address
Note
Substitution is a partial order. It is reflexive and transitive by the definition below. It is asymmetric because no cycles are allowed in substitution groups.
Semantics
The substitutes judgment for element names is specified by the following rules.
Every element name substitutes for itself.
Every element name substitutes for the element it is declared to substitute for.
|
|||
|
|||
statEnv |- ElementName substitutes for BaseElementName |
Substitution is transitive.
The name lookup judgment is used in the definition of the matches judgment, which takes a value and a type and determines whether the value matches, or is an instance of, the given type. Both name lookup and matches are used in the dynamic semantics.
The name lookup judgment takes an element(attribute) name (derived from a node value) and an element(attribute) type and if the element(attribute) name matches the corresponding name in the element(attribute) type, the judgment yields the type's corresponding type reference and for elements, its nillable property.
Notation
The judgment
holds when the given element name matches the given element type and requires that the element be nillable as indicated and have the given type reference.
Example
For example, assuming the extended XML Schema given in section [2.4.5 Example of a complete Schema], then the following judgments hold.
comment name lookup element comment yields of type xsd:string size name lookup element size nillable of type xs:integer yields nillable of type xsd:string apt name lookup element apt yields of type fs:anon3 nycaddress name lookup element address yields of type NYCAddress
Note that when the element name is in a substitution group, the
name lookup returns the type name corresponding to the original
element name (here the type NYCAddress
for the element
nycaddress
, instead of Address
for the
element address
).
Semantics
This judgment is specified by the following rules.
If the element type is a reference to a global element, then name lookup yields the type reference in the element declaration for the given element name. The given element name must be in the substitution group of the global element.
|
statEnv |- ElementName1 name lookup element ElementName2 yields OptNillable TypeReference |
If the given element name matches the element name in the element type, and the element type contains a type reference, then name lookup yields that type reference.
|
statEnv |- ElementName name lookup element ElementName OptNillable TypeReference yields OptNillable TypeReference |
If the element type has no element name but contains a type reference, then name lookup yields the type reference.
|
statEnv |- ElementName name lookup element * TypeReference yields TypeReference |
If the element type has no element name and no type reference,
then name lookup yields xs:anyType
.
|
statEnv |- ElementName name lookup element * yields of type
xs:anyType |
Notation
The judgment
holds when matching an attribute with the given attribute name against the given attribute type matches the type reference.
Example
For example, assuming the extended XML Schema given in section [2.4.5 Example of a complete Schema], then the following judgments hold.
orderDate name lookup attribute orderDate of type xsd:date yields of type xsd:date? orderDate name lookup attribute of type xsd:date yields of type xsd:date?
Semantics
This judgment is specified by the following rules.
If the attribute type is a reference to a global attribute, then name lookup yields the type reference in the attribute declaration for the given attribute name.
|
|||
|
|||
statEnv |- AttributeName name lookup attribute AttributeName yields TypeReference |
If the given attribute name matches the attribute name in the attribute type, and the attribute type contains a type reference, then name lookup yields that type reference.
|
statEnv |- AttributeName name lookup attribute AttributeName TypeReference yields TypeReference |
If the attribute type has no attribute name but contains a type reference, then name lookup yields the type reference.
|
statEnv |- AttributeName name lookup attribute * TypeReference yields TypeReference |
If the attribute type has no attribute name and no type
reference, then name lookup yields
xs:anySimpleType
.
|
statEnv |- AttributeName name lookup
attribute * yields of type
xs:anySimpleType |
The type lookup judgments are used to obtain the appropriate type reference for an attribute or element.
Notation
The judgment
holds when the element type is optionally nillable and has the given type reference.
Semantics
The element type lookup judgments are specified by the following rules.
A reference to a global element yields the type reference in the global element declaration with the given element name.
|
|||
|
|||
statEnv |- element ElementName type lookup OptNillable TypeReference |
In the case of a local element type, type lookup yields the corresponding type reference.
If the element type has no element name but contains a type reference, then type lookup yields that type reference.
|
statEnv |- element * OptNillable TypeReference type lookup TypeReference |
If the element type has no element name and no type reference,
then lookup yields xs:anyType
.
|
statEnv |- element * type lookup of type
xs:anyType |
Notation
The judgment
holds when the attribute type has the given type reference.
Semantics
This judgment is specified by the following rules.
A reference to a global attribute yields the type reference in the global attribute declaration with the given attribute name.
|
|||
|
|||
statEnv |- attribute AttributeName type lookup TypeReference |
If the attribute name is not defined, i.e., it is not declared
in the in-scope schema definitions, then the attribute's default
type is xs:untypedAtomic
.
|
|||
|
|||
statEnv |- attribute AttributeName type
lookup of type xs:untypedAtomic |
In the case of a local attribute type, type lookup yields the corresponding type reference.
|
statEnv |- attribute AttributeName TypeReference type lookup TypeReference |
If the attribute type has no attribute name but contains a type reference, then type lookup yields the type reference.
|
statEnv |- attribute * TypeReference type lookup TypeReference |
If the attribute type has no attribute name and no type
reference, then type lookup yields
xs:anySimpleType
.
|
statEnv |- attribute * type
lookup of type xs:anySimpleType |
Notation
The judgment
holds when the result of extending Type1 by Type2 is Type. This judgment is used in the definition of type expansion [8.1.9 Type expansion], which expands a type to include the union of all types derived from the given type,
Semantics
This judgment is specified by the following rules.
statEnv |- Type1 = AttributeModel1 , ElementModel1 statEnv |- Type2 = AttributeModel2 , ElementModel2 |
|
statEnv |- Type1 extended by Type2 is (AttributeModel1 & AttributeModel2) , ElementModel1 , ElementModel2 |
Notation
The judgment
holds when the result of creating a mixed content from Type1 is Type2.
Semantics
This judgment is specified by the following rule, which
interleaves the element content with a sequence of text nodes and
adds a union of xs:anyAtomicType
values.
The xs:anyAtomicType
sequence
is required because it is possible to derive an element containing
only atomic values from an element that is mixed.
statEnv |- Type = AttributeModel , ElementModel |
|
statEnv |- Type mixes to AttributeModel , ( ElementModel & text* |
xs:anyAtomicType
*) |
In the [XPath/XQuery] type system, a complex-type declaration does not include the implicit attributes and nodes that may be included in the type. Type adjustment takes a complex type and adjusts it to include implicit attributes and nodes. In particular, type adjustment:
adds the four (optional) built-in attributes xsi:type, xsi:nil, xsi:schemaLocation, or xsi:noNamespaceSchemaLocation,
interleaves the type with a sequence of comments and processing-instructions, and
if the complex type is mixed, interleaves the type with a
sequence of text nodes and xs:anyAtomicType
.
Notation
The judgment
holds when the second type is the same as the first after the first has been adjusted as described above.
Semantics
This judgment is specified by the following rules.
If the type is flagged as mixed, then mix the type and extend it by the built-in attributes.
|
||||
|
||||
statEnv |- mixed Type1 adjusts to Type4 |
Otherwise, just extend the type by the built-in attributes.
|
|||
|
|||
statEnv |- Type1 adjusts to Type3 |
Schema defines four built-in attributes that can appear on any element in the document without being explicitly declared in the schema. Those four attributes need to be added inside content models when doing matching. The four built-in attributes of Schema are declared as follows.
define attribute xsi:type of type xs:QName; define attribute xsi:nil of type xs:boolean; define attribute xsi:schemaLocation of type fs:anon; define type fs:anon1 { xs:anyURI* }; define attribute xsi:noNamespaceSchemaLocation of type xs:anyURI;
For convenience, a type that is an all group of the four built-in XML Schema attributes is defined.
BuiltInAttributes = attribute xsi:type ? & attribute xsi:nil ? & attribute xsi:schemaLocation ? & attribute xsi:noNamespaceSchemaLocation ?
The expands to judgment is one of the most important static judgments. It is used in the static semantics of the child axis [8.2.2.1 Static semantics of axes], which is used in the definition of many other rules that extract element types from an arbitrary content type.
The judgment takes a type name and computes the union of all types derived from the given type. If the type is nillable, it also makes sure the content model allows the empty sequence. If the type is mixed, it also adjusts the type to include the mixed content model. The judgment depends on the union interpretation of judgment to recursively compute all derived types.
Notation
The judgment
holds when expanding the type specifier results in the given type.
Semantics
This judgment is specified by the following rules.
If the type is nillable, then it expands into an optional type.
statEnv |- TypeReference expands to Type |
|
statEnv |- nillable TypeReference expands to Type? |
The type definition for the type reference is contained in its expansion.
|
|||||
|
|||||
statEnv |- of type TypeName expands to Type3 |
In case the type is xs:untyped
, the type does not
need to be adjusted as is required for other XML Schema types. See
the corresponding definition in [3.5.1 Predefined Schema
Types].
|
|||
|
|||
statEnv |- of type xs:untyped expands to Type1 |
Notation
The judgment
holds when the type TypeU is the union of all types derived (directly and indirectly, by extension and restriction) from the type defined by Definition.
Semantics
This judgment is specified by the following rules.
|
|||||||||
|
|||||||||
|
The auxilliary judgment
looks "up" the type hierarchy to find out what OptDerivation contributes to the content model of a derived type. It is defined as follows:
|
||||
|
||||
|
|
||
|
|
||
|
The auxiliary judgment:
holds when Type2 is the result of making Type1 'mixed' or not, as determined by OptMixed. It is defined as follows:
|
||
|
Finally, the auxiliary judgment:
is defined informally: all type definitions in statEnv.typeDefn that involve "restricts TypeName" or "extends TypeName" are returned as a list (in arbitrary order) of Definitions.
Examples
Note that this expansion does not enforce the unique
particule attribution property specified by XML Schema in the
resulting content models. Implementations may want to implement an
equivalent alternative expansion that enforces that property. For
example, expanding type T1
below yields the following
type that is not one-deterministic:
define type T1 { element a } define type T2 extends T1 { element b } union interpretation of define type T1 { element a } is (element a | element a, element b)
An implementation might want to infer the equivalent content model that verifies the unique particule attribution property of XML Schema:
union interpretation of define type T1 { element a } is (element a, (() | element b))
Introduction
Step expressions are one of the elementary operations in [XPath/XQuery]. Steps select nodes reachable from the root of an XML tree. Defining the semantics of step expressions requires a detailed analysis of all the possible cases of axis and node tests.
This section introduces auxiliary judgments used to define the semantics of step expressions. The has principal judgment ([8.2.1 Principal Node Kind]) captures the notion of principal node kind in XPath. The Axis judgments ([8.2.2 Auxiliary judgments for axes]) define the static and dynamic semantics of all axes, and the Node Test judgments ([8.2.3 Auxiliary judgments for node tests]) define the static and dynamic semantics of all node tests. The filter judgment accesses the value of an attribute and is used in the definition of validation ([F Auxiliary Judgments for Validation]).
Notation
The following auxiliary grammar production describes principal node kinds (See [XML Path Language (XPath) 2.0 (Second Edition)]).
[64 (Formal)] | PrincipalNodeKind |
::= | "element" | "attribute" | "namespace" |
Notation
The judgment
holds when PrincipalNodeKind is the principal node kind for Axis.
Example
For example, the following judgments hold.
child:: principal element descendant:: principal element preceding:: principal element attribute:: principal attribute namespace:: principal namespace
Semantics
This judgment is specified by the following rules.
The principal node type for the attribute axis is attribute.
|
attribute:: has principal attribute |
The principal node type for the namespace axis is namespace.
|
namespace:: has principal namespace |
The principal node type for all other axis is element.
Axis !=
attribute:: Axis !=
namespace:: |
|
Axis has principal element |
Notation
The following judgment
holds when applying the axis Axis on type Type1 yields the type Type2.
The following two judgments are used in the definition of axis. The judgment
only applies to a type that is a valid element content type and holds when Type1 has the content type Type2. The judgment separates the attribute types from the other node or atomic-valued types of the element content type and yields the non-attribute types.
The judgment
only applies to a type that is a valid element content type and holds when Type1 has attribute types Type2. The judgment yields the attribute types of the element content type.
Example
For example, the following judgments hold.
axis child:: of element of type xs:string : text axis child:: of element items of type Items : element item of type fs:anon1* axis child:: of element purchaseOrder : element shipTo of type USAddress, element billTo of type USAddress, element ipo:comment?, element items of type Items axis attribute:: of element of type xs:string : empty attribute partNum of type SKU, element item of type fs:anon1* has-node-content element item of type fs:anon1* attribute partNum of type SKU, element item of type fs:anon1* has-attribute-content attribute partNum of type SKU (attribute partNum of type SKU, element item of type fs:anon1*) | (attribute orderDate of type xs:date?, element shipTo of type USAddress, element billTo of type USAddress, element comment?, element items of type Items) has-node-content (element item of type fs:anon1*) | (element shipTo of type USAddress, element billTo of type USAddress, element comment?, element items of type Items) (attribute partNum of type SKU, element item of type fs:anon1*) | (attribute orderDate of type xs:date?, element shipTo of type USAddress, element billTo of type USAddress, element comment?, element items of type Items) has-attribute-content (attribute partNum of type SKU) | (attribute orderDate of type xs:date?)
Semantics
The following rules compute the type of the axis expression when applied to each item type in the content model.
|
||
|
||
statEnv |- axis Axis of Type1 OccurrenceIndicator : Type2 OccurrenceIndicator |
|
|||
|
|||
statEnv |- axis Axis of Type1&Type2 : Type3&Type4 |
|
|||
|
|||
statEnv |- axis Axis of Type1,Type2 : Type3,Type4 |
|
|||
|
|||
statEnv |- axis Axis of Type1|Type2 : Type3|Type4 |
The rules in the following subsections specify how to compute the type of each axis applied to an item type.
self
axisSemantics
Applying the self axis to a node type results in the same node type.
child
axisSemantics
In the case of an element type, the static type of the child axis is obtained by type lookup and expansion of the resulting type. Note that the expands to judgment yields the type that corresponds to a given type name. Because the meaning of a type name includes the definitions of all type names derived by extension and restriction from the given type name, expands to yields the union of all the type definitions of all type names derived from the input type name. Each type in the union contains the complete definition of the type name, i.e., it includes built-in attributes and, if necessary, processing-instruction, comment, and text types.
After type expansion, the judgment has node content is applied to each type in the union. The resulting type is the union of all non-attribute types in the expanded type.
|
||||||
|
||||||
statEnv |- axis child:: of ElementType : Type1'
| ... | Typen' |
If the type is a sequence of attributes, then the content type
is empty
.
If the type is attributes followed by a simple type, the content type is zero-or-one text nodes. The resulting type is optional since an expression returning the empty sequence results in no text node being constructed.
|
||||
|
||||
statEnv |- Type has node content text? |
In the case of an element type with complex content type, the content type is simply the non-attribute part of the complex content type.
|
||||
|
||||
statEnv |- Type has node content Type2 |
In the case of an attribute type, the static type of the child axis is empty.
|
statEnv |- axis child:: of AttributeType :
empty |
In the case of a text node type, the static type of the child axis is empty.
In the case of a comment node type, the static type of the child axis is empty.
In the case of a processing-instruction node type, the static type of the child axis is empty.
In case of a document node type, the static type of the child axis is the type of the document node content, interleaved with a sequence of comments and processing-instructions.
attribute
axisSemantics
The static type for the attribute axis is computed in a similar way as the static type for the child axis. As above, the expands to judgment may yield a union type. After type expansion, the judgment has attribute content is applied to each type in the union.
|
||||||
|
||||||
statEnv |- axis attribute:: of ElementType : Type1'
| ... | Typen' |
When applied to an element type, has attribute content yields the type of the element's content that are attributes.
|
||||
|
||||
statEnv |- Type has attribute content Type1 |
In case of an attribute type, the static type of the attribute axis is empty.
|
statEnv |- axis attribute:: of AttributeType :
empty |
In case of a text node type, the static type of the attribute axis is empty.
In case of a comment node type, the static type of the attribute axis is empty.
In case of a processing-instruction node type, the static type of the attribute axis is empty.
In case of a document node type, the static type of the attribute axis is the empty.
parent
axisSemantics
The type for the parent of an element type, a text node type, a PI node type, or a comment node type is either an element, a document, or empty.
The type for the parent of an attribute node is an element or empty.
|
statEnv |- axis parent:: of AttributeType : element *? |
The type for the parent of a document node type is always empty.
|
statEnv |- axis parent:: of DocumentType :
empty |
namespace
axisSemantics
This document does not specify inference rules for the namespace axis (which is allowed, though deprecated, in XPath 2.0, and is not allowed in XQuery 1.0). Implementations choosing to support the namespace axis will need to define an additional node kind for namespace nodes in the type hierarchy, and to add the appropriate inference rules.
descendant
axisSemantics
The types for the descendant axis is obtained as the closure of the type of the child axis. This is expressed by the following inference rule.
|
||||||
|
||||||
statEnv |- axis descendant:: of Type : (prime(Type1)
| ... | prime(Typen))* |
Note
Note that the last premise in the above rule terminates the recursion. The rule computes the n-th type Typen such that applying the child axis one more time does not add any new item type to the union. This condition is guaranteed to hold at some point, because the number of item types is bounded by all of the item types defined in the in-scope schema definitions.
descendant-or-self
axisSemantics
The type for the descendant-or-self axis is the union of the type for the self axis and for the descendant axis.
ancestor
axisSemantics
The type for the ancestor axis is computed similarly as for the descendant axis.
Note that this rule will always result in the type
(element * | document)*
type, but this formulation is
preferred for consistency, and in case the static typing for the
parent axis gets improved in a future version.
Notation
The following judgment
holds when applying the axis Axis on Value1 yields Value2:
Example
For example, the following judgments hold.
axis child:: of element sizes { text { "1 2 3" } } => text { "1 2 3" } axis attribute:: of element weight of type xs:integer { attribute xsi:type of type xs:QName { "xs:integer" of type xs:QName }, 42 of type xs:integer } => attribute xsi:type of type xs:QName { "xs:integer" of type xs:QName }
Semantics
This judgment is specified by the following rules.
The first set of rules are used to process the axis judgment on each individual item in the input sequence.
|
|||
|
|||
dynEnv |- axis Axis of Value1,Value2 => Value3,Value4 |
The following rules specifies how the value filter judgment is applied on each Axis.
The self axis just returns the context node.
The child, parent, attribute and namespace axis are specified as follows.
|
dynEnv |- axis child:: of element ElementName { AttributeValue,ElementValue } => ElementValue |
|
dynEnv |- axis attribute:: of element ElementName { AttributeValue,ElementValue } => AttributeValue |
The descendant, descendant-or-self, ancestor, and ancestor-or-self axis are implemented through recursive application of the children and parent filters.
|
|||
|
|||
dynEnv |- axis descendant:: of NodeValue => Value1, Value2 |
|
|||
|
|||
dynEnv |- axis descendant-or-self::
of NodeValue => Value1, Value2 |
|
|||
|
|||
dynEnv |- axis ancestor:: of NodeValue => Value1, Value2 |
|
|||
|
|||
dynEnv |- axis ancestor-or-self:: of NodeValue => Value1, Value2 |
In all the other cases, the axis application results in an empty sequence, and the following judgment holds.
A node test may be a name test or a kind test. In the static and dynamic semantics, we begin with name tests, followed by kind tests.
Notation
The following judgment
holds when applying the node test NodeTest on the type Type1 in the context of the given principal node kind, yields the type Type2.
Example
For example, assuming the extended XML Schema given in section [2.4.5 Example of a complete Schema], then the following judgments hold.
test shipTo with element of element shipTo of type USAddress, element billTo of type USAddress, element ipo:comment?, element items of type Items : element shipTo of type USAddress
Semantics
This judgment is specified by the following rules.
The first set of rules is similar to that for axes, and are used to process the content each individual item type in the input content model.
statEnv |- test NodeTest with PrincipalNodeKind of Type1 : Type2 |
|
statEnv |- test NodeTest with PrincipalNodeKind of Type1 OccurrenceIndicator : Type2 OccurrenceIndicator |
|
|||
|
|||
statEnv |- test NodeTest with PrincipalNodeKind of Type1 & Type2 : Type3 & Type4 |
|
|||
|
|||
statEnv |- test NodeTest with PrincipalNodeKind of Type1 , Type2 : Type3 , Type4 |
|
|||
|
|||
statEnv |- test NodeTest with PrincipalNodeKind of Type1|Type2 : Type3|Type4 |
The following rules specify how the test judgment apply to node tests in the context of a principal node kind. We start with name tests followed by kind tests.
Name tests on elements and attributes always compute the most
specific type possible. For example, if $v
is bound to
an element with a computed name, the type of $v
is
element
. The static type computed for the expression
$v/self::foo
is element foo of type
xs:anyType
, which makes use of foo
in the name
test to compute a more specific type. Also note that each case of
name matching restricts the principal node kind appropriately.
|
|||
|
|||
statEnv |- test QName2 with element of element QName1 OptTypeSpecifier : element QName1 OptTypeSpecifier |
|
||||
|
||||
|
|
statEnv |- test QName2 with element of element * OptTypeSpecifier : element
QName2 OptTypeSpecifier ? |
|
|||
|
|||
statEnv |- test
*: LocalPart2
with element
of element
QName1 OptTypeSpecifier : element
QName1 OptTypeSpecifier |
|
||||
|
||||
|
|
statEnv |- test
*: LocalPart2
with element
of element *
OptTypeSpecifier
: element *
OptTypeSpecifier
? |
|
||||
|
||||
statEnv |- test Prefix2:* with element of element QName1 OptTypeSpecifier : element QName1 OptTypeSpecifier |
|
|||||
|
|||||
|
|
statEnv |- test Prefix2:* with element of element * OptTypeSpecifier : element * OptTypeSpecifier ? |
|
statEnv |- test * with element of ElementType : ElementType |
Similar static typing rules apply to the attribute name tests:
|
|||
|
|||
statEnv |- test QName2 with attribute of attribute QName1 OptTypeReference : attribute QName1 OptTypeReference |
|
||||
|
||||
|
|
statEnv |- test QName2 with attribute of attribute * OptTypeReference : attribute
QName2 OptTypeReference ? |
|
|||
|
|||
statEnv |- test
*: LocalPart2
with attribute
of attribute
QName1 OptTypeReference : attribute
QName1 OptTypeReference |
|
||||
|
||||
|
|
statEnv |- test
*: LocalPart2
with attribute
of attribute *
OptTypeReference
: attribute *
OptTypeReference
? |
|
||||
|
||||
statEnv |- test Prefix2:* with attribute of attribute QName1 OptTypeReference : attribute
QName1 OptTypeReference |
|
|||||
|
|||||
|
|
statEnv |- test Prefix2:* with attribute of attribute * OptTypeReference : attribute * OptTypeReference ? |
|
statEnv |- test * with attribute of AttributeType : AttributeType |
All the rules for typing the document, element, and attribute kind tests are similar. First, the document, element, or attribute test is normalized to the equivalent document, element, or attribute type by applying the []sequencetype normalization rule to the kind test.
After normalization of the kind test as an XQuery type, that type is compared to the expression's inferred type. If the latter is a subtype of the former other, then the kind test yields the smaller type.
Document kind test
Semantics
If the type of the expression is a subtype of the document kind test, then we are guaranteed that during evaluation, the expression's value will always match the document kind test, and therefore the type of the entire expression is the type of the input expression.
|
|||
|
|||
statEnv |- test DocumentTest with element of Type1 : Type1 |
Conversely, if the type of the document kind test is a subtype of the expression, then during evaluation, the expression's value may or may not match the document kind test, and therefore the type of the entire expression is zero-or-one of the type of the document kind test.
|
|||
|
|||
statEnv |- test DocumentTest with element of Type1 : DocumentType? |
If the types of the expression and document kind test are unrelated, then we apply the kind test rule recursively on the element types, which may yield a non-empty type.
|
|||||
|
|||||
statEnv |- test document-node (ElementTest) with element of document { Type1 } : document { Type2 } |
If there is no non-empty type, then the kind test yields the empty type.
|
||||||
|
||||||
statEnv |- test document-node (ElementTest) with element of document { Type1 } : empty |
Element kind test
Semantics
The rules for the element kind test are similar to those for the document kind test.
If the type of the expression is a subtype of the element kind test, then we are guaranteed that during evaluation, the expression's element value will always match the element kind test, and therefore the type of the entire expression is the type of the input expression.
|
|||
|
|||
statEnv |- test ElementTest with element of Type1 : Type1 |
Conversely, if the type of the element kind test is a subtype of the expression, then during evaluation, the expression's element value may or may not match the element kind test, and therefore the type of the entire expression is zero-or-one of the type of the element kind test.
|
|||
|
|||
statEnv |- test ElementTest with element of Type1 : ElementType? |
If the types of the expression and element kind test are unrelated (i.e., neither type is a subtype of the other), then we must compare the structure of the type of the element test with the type of the element expression, as an element type or test may contain wildcards.
In the first case, the element kind test contains an element name and a type name and the input expression's type contains only a type name. If the input expression's content type is a subtype of the element kind test's content type, then the type of the entire expression is zero-or-one of an element with the given name and the input expression's content type.
|
||||
|
||||
statEnv |- test ElementTest with element of element * TypeSpecifier2 : element ElementName1 TypeSpecifier2? |
In the second case, the structure of the input types is reversed: The input expression's type contains an element name and a type name and the element kind test's type contains only a type name. If the element kind test's content type is a subtype of the input expression's content type, then the type of the entire expression is zero-or-one of an element with the given name and the element kind test's content type.
|
||||
|
||||
statEnv |- test ElementTest with element of element ElementName2 TypeSpecifier2 : element ElementName2 TypeSpecifier1? |
Lastly, if none of the above rules holds, then the type of the input expression is empty.
|
||||||||
|
||||||||
statEnv |- test ElementTest with element of element ElementNameOrWildcard2 TypeSpecifier2 : empty |
Attribute kind test
Semantics
The rules for the attribute kind test are isomorphic to those for element kind test.
If the type of the expression is a subtype of the attribute kind test, then we are guaranteed that during evaluation, the expression's attribute value will always match the attribute kind test, and therefore the type of the entire expression is the type of the input expression.
|
|||
|
|||
statEnv |- test AttributeTest with attribute of Type1 : Type1 |
Conversely, if the type of the attribute kind test is a subtype of the expression, then during evaluation, the expression's attribute value may or may not match the attribute kind test, and therefore the type of the entire expression is zero-or-one of the type of the attribute kind test.
|
|||
|
|||
statEnv |- test AttributeTest with attribute of Type1 : AttributeType? |
If the types of the expression and attribute kind test are unrelated (i.e., neither type is a subtype of the other), then we must compare the structure of the type of the attribute test with the type of the attribute expression, as an attribute type or test may contain wildcards.
In the first case, the attribute kind test contains an attribute name and a type name and the input expression's type contains only a type name. If the input expression's content type is a subtype of the attribute kind test's content type, then the type of the entire expression is zero-or-one of an attribute with the given name and the input expression's content type.
|
||||
|
||||
statEnv |- test AttributeTest with attribute of attribute * TypeReference2 : attribute AttributeName1 TypeReference2? |
In the second case, the structure of the input types is reversed: The input expression's type contains an attribute name and a type name and the attribute kind test's type contains only a type name. If the attribute kind test's content type is a subtype of the input expression's content type, then the type of the entire expression is zero-or-one of an attribute with the given name and the attribute kind test's content type.
|
||||
|
||||
statEnv |- test AttributeTest with attribute of attribute AttributeName2 TypeReference2 : attribute AttributeName2 TypeReference1? |
Lastly, if none of the above rules holds, then the type of the input expression is empty.
|
||||||||
|
||||||||
statEnv |- test AttributeTest with attribute of attribute AttributeName2 TypeReference2 : empty |
Processing instruction, comment, and text kind tests
Semantics
[PITest]sequencetype = processing-instruction * |
|
statEnv |- test PITest with PrincipalNodeKind of ProcessingInstructionType : ProcessingInstructionType |
A processing-instruction node test with a string literal or NCName matches a processing instruction whose target has the given name.
[PITest]sequencetype = processing-instruction NCName |
|
statEnv |- test PITest with PrincipalNodeKind of processing-instruction NCName : processing-instruction NCName |
[PITest]sequencetype = processing-instruction NCName |
|
statEnv |- test PITest with PrincipalNodeKind of processing-instruction * : processing-instruction NCName ? |
If none of the above rules applies then the node test returns the empty sequence, and the following dynamic rule is applied:
Notation
The following judgment
holds when applying the node test NodeTest on Value1 in the context of the PrincipalNodeKind yields Value2:
Example
For example, the following judgments hold.
test node() with element of text { "1 2 3" } => text { "1 2 3" } test size with element of text { "1 2 3" } => () test foo:* with element of (element foo:a of type xs:int { 1 }, element foo:a of type xs:int { 2 }, element bar:b of type xs:int { 3 }, element bar:c of type xs:int { 4 }, element foo:d of type xs:int { 5 }) => (element foo:a of type xs:int { 1 }, element foo:a of type xs:int { 2 }, (), (), element foo:d of type xs:int { 5 })
Note
The last example illustrates how a test judgment operates on a sequence of nodes, applying the test on each node in the sequence individually, while preserving the structure of the sequence.
Semantics
This judgment is specified by the following rules.
The first set of rules are similar to those for axes, and are used to process the test judgment on each individual item in the input sequence.
|
|||
|
|||
dynEnv |- test NodeTest with PrincipalNodeKind of Value1,Value2 => Value3,Value4 |
The following rules specify how the value filter judgment is applied on a name test in the context of a principal node kind.
Semantics
|
||||||
|
||||||
dynEnv |- test Prefix:LocalPart with PrincipalNodeKind of NodeValue => NodeValue |
|
||
|
||
dynEnv |- test * with PrincipalNodeKind of NodeValue => NodeValue |
|
|||||
|
|||||
dynEnv |- test Prefix:* with
PrincipalNodeKind of NodeValue => NodeValue |
All the rules for evaluating the document, element, and attribute kind tests are similar. First, the document, element, or attribute test is normalized to the equivalent document, element, or attribute type by applying the []sequencetype normalization rule. As explained in [3.5.3 SequenceType Syntax], SequenceTypes are normalized to XQuery types whenever a dynamic evaluation or static typing rule requires the corresponding type. The reason for this deviation from the processing model is that the result of SequenceType normalization is not part of the [XPath/XQuery] core syntax.
After normalization of the SequenceType to an XQuery type, the document, element, or attribute value is simply matched against the XQuery type. If the value matches the type, then the judgment yields the value, otherwise the judgment yields the empty sequence.
Document kind test
Semantics
|
|||
|
|||
dynEnv |- test DocumentTest with element of DocumentValue => DocumentValue |
|
|||
|
|||
dynEnv |- test DocumentTest with element of DocumentValue => () |
Element kind test
Semantics
|
|||
|
|||
dynEnv |- test ElementTest with element of ElementValue => ElementValue |
|
|||
|
|||
dynEnv |- test ElementTest with element of ElementValue => () |
Attribute kind test
Semantics
|
|||
|
|||
dynEnv |- test AttributeTest with attribute of AttributeValue => AttributeValue |
|
|||
|
|||
dynEnv |- test AttributeTest with attribute of AttributeValue => () |
Processing instruction, comment, and text kind tests
Semantics
|
||
|
||
dynEnv |- test processing-instruction()
with
PrincipalNodeKind of NodeValue => NodeValue |
|
|||||
|
|||||
dynEnv |- test processing-instruction(
StringLiteral ) with PrincipalNodeKind of NodeValue => NodeValue |
|
||
|
||
dynEnv |- test processing-instruction()
with
PrincipalNodeKind of NodeValue => () |
|
||
|
||
dynEnv |- test comment() with
PrincipalNodeKind of NodeValue => NodeValue |
|
||
|
||
dynEnv |- test comment() with
PrincipalNodeKind of NodeValue => () |
|
||
|
||
dynEnv |- test text() with PrincipalNodeKind
of NodeValue => NodeValue |
|
||
|
||
dynEnv |- test text() with PrincipalNodeKind
of NodeValue => () |
The node()
node test is true for all nodes.
Therefore, the following rule does not have any precondition
(remember that an empty upper part in the rule indicates that the
rule is always true).
If none of the above rules applies then the node test returns the empty sequence, and the following dynamic rule is applied:
Introduction
XQuery supports type declarations on variable bindings, and
several operations on types (typeswitch
,
instance of
, etc). This section describes judgments
used for the specification of the semantics of those
operations.
The "match" judgment specifies formally type matching. It takes as input a value and a type and either succeeds or fails. It is used in matching parameters against function signatures, type declarations, and matching values against cases in "typeswitch". An informal description of type matching is given in Section 2.5.4 SequenceType MatchingXQ.
The "subtyping" judgment takes two types and succeeds if all values matching the first type also match the second. It is used to define the static semantics of operations using type matching.
Notation
The judgment
holds when the given value matches the given type.
Example
For example, assuming the extended XML Schema given in section [2.4.5 Example of a complete Schema], then the following judgments hold.
element comment of type xsd:string { "This is not important" } matches element comment of type xsd:string (element apt of type fs:anon3 { 2510 }, element apt of type fs:anon3 { 2511 }) matches element apt+ () matches element usaddress? element usaddress of type USAddress { element name of type xsd:string { "The Archive" }, element street of type xsd:string { "Christopher Street" }, element city of type xsd:string { "New York" }, element state of type xsd:string { "NY" }, element zip of type xsd:decimal { 10210 } } matches element usaddress?
Semantics
We start by giving the inference rules for matching an item value with an item type.
An atomic value matches an atomic type if its type annotationXQ derives from the atomic type. The value itself is ignored -- this is checked as part of validation.
statEnv |- AtomicTypeName1 derives from AtomicTypeName2 |
|
statEnv |- AtomicValueContent of type AtomicTypeName1 matches AtomicTypeName2 |
A text node matches text.
A comment node matches comment.
A processing-instruction node matches the general processing-instruction type, and also the particular processing-instruction type that shares its PITarget.
A document node matches a document type if the node's content matches the document type's corresponding content type.
The rules for matching an element value with an element type are more complicated. When an element value is not nilled, the element matches an element type if the element name and the element type resolve to some type name, and the element value's type annotationXQ is derived from the resolved type name. Note that there is no need to check structural constraints on the value since those have been checked during XML Schema validation and the value is assumed to be consistent with its type annotationXQ.
|
|||||
|
|||||
statEnv |- element ElementName of type TypeName { Value } matches ElementType |
Note
Type matching uses the name lookup judgment defined in [8.1.3 Element and attribute name lookup (Dynamic)].
In the case the element has been nilled, that is there exists and xsi:nil attribute set to true in the element value, the following rule checks that the type is nillable.
|
||||
|
||||
statEnv |- element ElementName of type TypeName { Value } matches ElementType |
The rule for attributes is similar, but does not require the check for the xsi:nil attribute.
|
|||
|
|||
statEnv |- attribute AttributeName of type TypeName { SimpleValue } matches AttributeType |
A type can also be a sequence of items, in that case the matching rules also need to check whether the constraints described by the type as a regular expression hold. This is specified by the following rules.
The empty sequence matches the empty sequence type.
If two values match two types, then their sequence matches the corresponding sequence type.
|
|||
|
|||
statEnv |- Value1,Value2 matches Type1,Type2 |
If a value matches a type, then it also matches a choice type where that type is one of the choices.
If two values match two types, then their interleaving matches the corresponding all group.
|
||||
|
||||
statEnv |- Value matches Type1 & Type2 |
An optional type matches a value of that type or the empty sequence.
The following rules are used to match a value against a sequence of zero (or one) or more types.
statEnv |- Value1 matches Type statEnv |- Value2 matches Type* |
|
statEnv |- Value1, Value2 matches Type* |
statEnv |- Value1 matches Type statEnv |- Value2 matches Type* |
|
statEnv |- Value1, Value2 matches Type+ |
Note
The above definition of type matching, although complete and precise, does not give a simple means to compute type matching. Notably, some of the above rules can be non-deterministic (e.g., the rule for matching of choice or repetition).
The structural component of the [XPath/XQuery] type system can be modeled by regular expressions. Regular expressions can be implemented by means of finite state automata. Computing type matching then is equivalent to check if a given sequence of items is recognized by its corresponding finite state automata. Finite state automata and their relationships to regular expressions have been extensively studied and documented in computer-science literature. The interested reader can consult the relevant literature, for instance [Languages], or [TATA].
Introduction
This section defines the semantics of subtyping in [XPath/XQuery]. Subtyping is used during static type analysis, in typeswitch, treat and assert expressions, and to check the correctness of function applications.
Note that intuitive relationships between types. For instance, that (Type,()) is equivalent to Type can be deduced using the subtyping judgment (and algorithm) described here.
Notation
The judgment
holds if the first type is a subtype of the second.
Semantics
This judgment is true if and only if, for every value Value, if Value matches Type1 holds, then Value matches Type2 also holds.
Note
It is easy to see that the subtype relation <: is a partial order, i.e. it is reflexive:
statEnv |- Type <: Typeand it is transitive: if,
statEnv |- Type1 <: Type2and,
statEnv |- Type2 <: Type3then,
statEnv |- Type1 <: Type3Finally, two types are equal if each is a subtype of the other, that is:
statEnv |- Type1 <: Type2and,
statEnv |- Type2 <: Type1then,
statEnv |- Type1 = Type2Note
The above definition, although complete and precise, does not give a simple means to compute subtyping. Notably the definition above refers to values, which are not available at static type checking time.
The structural component of the [XPath/XQuery] type system can be modeled by regular expressions. Regular expressions can be implemented by means of finite state automata. Computing subtyping between two types can then be done by computing if inclusion holds between their corresponding finite state automata.
Finite state automata and how to compute operations on those automata, such as inclusion, emptiness or intersection, have been extensively studied and documented in the literature. The interested reader can consult the relevant literature on tree grammars, for instance [Languages], or [TATA].
Introduction
Some [XPath/XQuery] operations work on sequences of items. For
instance, [For/FLWOR] expressions iterate over a sequence of items
and the fn:unordered
function can return all items in
a sequence in any order, etc.
Static typing for those operations needs to infer a type acceptable for all the items in the sequence. This sometimes requires approximating the type known for each item individually.
Example
Assume the variable $shipTo
is bound to the shipTo
element
<shipTo country="US"> <name>Alice Smith</name> <street>123 Maple Street</street> <city>Mill Valley</city> <state>CA</state> <zip>90952</zip> </shipTo>
and has type
element shipTo of type USAddress
The following query orders all children of the shipTo element by alphabetical order of their content.
for $x in $shipTo/* order by $x/text() return $x
resulting in the sequence
(<street>123 Maple Street</street>, <zip>90952</zip>, <name>Alice Smith</name>, <state>CA</state>, <city>Mill Valley</city>)
This operation iterates over the elements in the input sequence
returned by the expression $shipTo/*
, whose type is
the content of a type USAddress.
(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)
During static typing, one must give a type to the variable
$x
which corresponds to the type of each element in
the sequence. Since each item is of a different type, one must find
an item type which is valid for all cases in the sequence. This can
be done by using a choice for the variable $x
, as
follows
(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)
This type indicates that the type of the variable can be of any of the item types in the input sequence.
The static inference also needs to approximate the number of
occurrences of items in the sequence. In this example, there is at
least one item and more than one, so the closest occurrence
indicator is +
for one or more items.
The static inference for this example finally results in the following type.
(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)+
[Definition: A prime type is a choice of item types.] This section defines two functions on types that compute the prime type of an arbitrary type, and approximate the occurrence of items in an arbitrary type. These type functions are used in the static semantics of many expressions, including "for", "some", and "every" expressions, and many functions, including "fn:unordered" and "fn:distinct-values".
Notation
A choice of item types is called a prime type, as described by the following grammar production.
[44 (Formal)] | PrimeType |
::= | FormalItemType |
Notation
The type function prime(Type) extracts all item types from the type Type, and combines them into a choice.
The function quantifier(Type)
approximates the possible number of items in Type with the occurrence indicators
supported by the [XPath/XQuery] type system (?, +,
*
).
For interim results, the auxiliary occurrence indicator
1
denotes exactly one occurrence.
Semantics
The prime function is defined by induction as follows.
prime(FormalItemType) | = | FormalItemType |
prime(empty ) |
= | none |
prime(none ) |
= | none |
prime(Type1 , Type2) | = | prime(Type1) | prime(Type2) |
prime(Type1 & Type2) | = | prime(Type1) | prime(Type2) |
prime(Type1 | Type2) | = | prime(Type1) | prime(Type2) |
prime(Type?) | = | prime(Type) |
prime(Type*) | = | prime(Type) |
prime(Type+) | = | prime(Type) |
Note
This function is typically used in judgments of the form:
In cases where prime(Type) =
none
, there may be a temptation to bind FormalItemType1
to none
and n
to 1
. However,
it is important to note that none
is not a FormalItemType, rather it is
equivalent to a union type with no member types. Thus, in such
cases, the proper way to satisfy the given judgment is to bind
n
to 0
.
Semantics
The quantifier function is defined by induction as follows.
quantifier(FormalItemType) | = | 1 |
quantifier(empty ) |
= | ? |
quantifier(none ) |
= | 1 |
quantifier(Type1 , Type2) | = | quantifier(Type1) , quantifier(Type2) |
quantifier(Type1 & Type2) | = | quantifier(Type1) , quantifier(Type2) |
quantifier(Type1 | Type2) | = | quantifier(Type1) | quantifier(Type2) |
quantifier(Type?) | = | quantifier(Type) · ? |
quantifier(Type*) | = | quantifier(Type) · * |
quantifier(Type+) | = | quantifier(Type) · + |
This definition uses the sum (OccurrenceIndicator1 , OccurrenceIndicator2), the choice (OccurrenceIndicator1 | OccurrenceIndicator2), and the product (OccurrenceIndicator1 · OccurrenceIndicator2) of two occurrence indicators OccurrenceIndicator1, OccurrenceIndicator2, which are defined by the following tables.
|
|
|
Examples
For example, here are the result of applying prime and quantifier on a few simple types.
prime(element a+) = element a prime(element a | empty) = element a prime(element a?,element b?) = element a | element b prime(element a | element b+, element c*) = element a | element b | element c quantifier(element a+) = + quantifier(element a | empty) = ? quantifier(element a?,element b?) = * quantifier(element a | element b+, element d*) = +
Note that the last occurrence indicator should be '+', since the regular expression is such that there must be at least one element in the sequence (this element being an 'a' element or a 'b' element).
Note
Note that prime(Type) · quantifier(Type) is always a super type of the original type Type I.e., Type <: prime(Type) · quantifier(Type) always holds. Therefore, it is appropriate to used it as an approximation for the type of an expression. This property is required for the soundness of the static type analysis.
Semantics
Finally, a type Type and an occurrence indicator can be combined back together to yield a new type with the · operation, as follows.
Type · 1 | = | Type |
Type · ? | = | Type? |
Type · + | = | Type+ |
Type · * | = | Type* |
Introduction
Function calls can perform type promotion between atomic types.
This section introduces judgments which describe type promotion for
the purpose of the dynamic and static semantics. These promotion
rules include promoting xs:untypedAtomic
to any
other type.
Notation
The judgment
holds if type Type1 can be promoted to type Type2.
Example
For example, the following judgments hold:
xs:integer can be promoted to xs:integer xs:decimal can be promoted to xs:float xs:integer can be promoted to xs:float xs:float can be promoted to xs:double
Semantics
This judgment is specified by the following rules.
xs:decimal
can be promoted to
xs:float
:
|
||
|
xs:float
can be promoted to
xs:double
:
|
||
|
xs:anyURI
can be promoted to
xs:string
:
|
||
|
xs:untypedAtomic
can be promoted to any atomic type:
A type can be promoted to itself or to any type of which it is a subtype:
Type promotion is transitive:
statEnv |- Type1 can be promoted to Type2 statEnv |- Type2 can be promoted to Type3 | ||
|
||
|
Finally, type promotion distributes over occurrence and union constructors.
statEnv |- prime(Type1) can be promoted to prime(Type2) quantifier(Type1) <= quantifier(Type2) | ||
|
||
|
statEnv |- Type1 can be promoted to Type statEnv |- Type2 can be promoted to Type | ||
|
||
|
where the "<=" operator for occurrence indicators denotes set inclusion of the subsets of the allowed occurrences.
Notation
The judgment
holds if value Value1 can be promoted to the value Value2 against the type Type2.
Example
For example, the following judgments hold
1 of type xs:integer against xs:integer promotes to 1 of type xs:integer 1 of type xs:integer against xs:decimal promotes to 1 of type xs:integer 1 of type xs:integer against xs:float promotes to 1.0e0 of type xs:float 1.0e0 of type xs:float against xs:double promotes to 1.0e0 of type xs:double
Note that type promotion changes the value, and only occurs if the input value does not match the target type.
Semantics
This judgment is specified by the following rules.
If the value matches the target type, then it is promoted to itself
If the value does not match the target type, but is an atomic value and it matches a type which can be promoted to the target type, then the value is cast to the target type.
Notation
A validation mode may occur explicitly in a validate expression [4.13 Validate Expressions]. The following with mode judgment resolves an element name within a given validation mode to the type that the element name denotes. The judgment is used in the semantics of the validate expression and in sequence type.
The judgment
holds when the possibly optional element name resolves to the given type in the given validation mode.
Semantics
We start with the rules for the global validation context.
If no element name is present, the global validation context resolves to the union of all element types that are globally declared.
|
|||||||
|
|||||||
statEnv |- * with mode ValidationMode resolves to (element ElementName1 | ... | element ElementNamen) |
If the element name is globally declared in the schema, it resolves to the element type of the corresponding global element declaration, independently of the validation mode.
|
|||
|
|||
statEnv |- ElementName with mode ValidationMode resolves to element ElementName |
If an element name is not globally defined and the validation mode is lax, then the element name resolves to the element type with the given element name with any content type.
|
|||
|
|||
statEnv |- ElementName with mode
lax resolves to element ElementName of type
xs:anyType |
This section contains the set of productions for the of [XPath/XQuery] grammar after it has been normalized, sometimes referred to as the "core" grammar, and for the formal grammar productions.
The following grammar uses the same Basic EBNF notation as [XML], except that grammar symbols always have initial capital letters. The EBNF contains the lexemes embedded in the productions.
[99] | IntegerLiteral |
::= | Digits |
[100] | DecimalLiteral |
::= | ("." Digits) | (Digits "." [0-9]*) |
[101] | DoubleLiteral |
::= | (("." Digits) | (Digits ("." [0-9]*)?)) [eE] [+-]? Digits |
[102] | StringLiteral |
::= | ('"' (EscapeQuot |
[^"])* '"') | ("'" (EscapeApos
| [^'])* "'") |
[103] | EscapeQuot |
::= | '""' |
[104] | EscapeApos |
::= | "''" |
[105] | ElementContentChar |
::= | Char -
[{}<&] |
[106] | QuotAttrContentChar |
::= | Char -
["{}<&] |
[107] | AposAttrContentChar |
::= | Char -
['{}<&] |
[108] | PITarget |
::= | [http://www.w3.org/TR/REC-xml#NT-PITarget]XML |
[109] | QName |
::= | [http://www.w3.org/TR/REC-xml-names/#NT-QName]Names |
[110] | NCName |
::= | [http://www.w3.org/TR/REC-xml-names/#NT-NCName]Names |
[111] | S |
::= | [http://www.w3.org/TR/REC-xml#NT-S]XML |
[112] | Char |
::= | [http://www.w3.org/TR/REC-xml#NT-Char]XML |
[1] | ModuleDecl |
::= | "module" "namespace" NCName "=" URILiteral Separator |
[2] | Separator |
::= | ";" |
[3] | NamespaceDecl |
::= | "declare" "namespace" NCName "=" URILiteral |
[4] | DefaultNamespaceDecl |
::= | "declare" "default" ("element" | "function") "namespace"
URILiteral |
[5] | OptionDecl |
::= | "declare" "option" QName
StringLiteral |
[6] | OrderingModeDecl |
::= | "declare" "ordering" ("ordered" |
"unordered") |
[7] | EmptyOrderDecl |
::= | "declare" "default" "order" "empty" ("greatest" |
"least") |
[8] | CopyNamespacesDecl |
::= | "declare" "copy-namespaces" PreserveMode "," InheritMode |
[9] | PreserveMode |
::= | "preserve" | "no-preserve" |
[10] | InheritMode |
::= | "inherit" | "no-inherit" |
[11] | DefaultCollationDecl |
::= | "declare" "default" "collation" URILiteral |
[12] | BaseURIDecl |
::= | "declare" "base-uri" URILiteral |
[13] | SchemaImport |
::= | "import" "schema" SchemaPrefix? URILiteral ("at" URILiteral ("," URILiteral)*)? |
[14] | SchemaPrefix |
::= | ("namespace" NCName "=")
| ("default" "element" "namespace") |
[15] | ModuleImport |
::= | "import" "module" ("namespace" NCName "=")? URILiteral ("at" URILiteral ("," URILiteral)*)? |
[16] | VarDecl |
::= | "declare" "variable" "$" QName TypeDeclaration? ((":=" ExprSingle) | "external") |
[17] | ConstructionDecl |
::= | "declare" "construction" ("strip" |
"preserve") |
[18] | FunctionDecl |
::= | "declare" "function" QName
"(" ParamList? ")" ("as"
SequenceType)? (EnclosedExpr |
"external") |
[19] | ParamList |
::= | Param ("," Param)* |
[20] | Param |
::= | "$" QName TypeDeclaration? |
[21] | EnclosedExpr |
::= | "{" Expr "}" |
[22] | Expr |
::= | ExprSingle (","
ExprSingle)* |
[23] | ExprSingle |
::= | FLWORExpr |
[24] | FLWORExpr |
::= | (ForClause | LetClause) "return" ExprSingle |
[25] | ForClause |
::= | "for" "$" VarName
TypeDeclaration? PositionalVar? "in" ExprSingle |
[26] | PositionalVar |
::= | "at" "$" VarName |
[27] | LetClause |
::= | "let" "$" VarName
TypeDeclaration? ":="
ExprSingle |
[28] | OrderByClause |
::= | (("order" "by") | ("stable" "order" "by")) OrderSpecList |
[29] | OrderSpecList |
::= | OrderSpec (","
OrderSpec)* |
[30] | OrderSpec |
::= | ExprSingle OrderModifier |
[31] | OrderModifier |
::= | ("ascending" | "descending")? ("empty" ("greatest" |
"least"))? ("collation" URILiteral)? |
[32] | QuantifiedExpr |
::= | ("some" | "every") "$" VarName TypeDeclaration? "in" ExprSingle ("," "$" VarName TypeDeclaration? "in" ExprSingle)* "satisfies" ExprSingle |
[33] | TypeswitchExpr |
::= | "typeswitch" "(" Expr ")"
CaseClause+ "default" "$"
VarName "return" ExprSingle |
[34] | CaseClause |
::= | "case" "$" VarName "as"
SequenceType "return"
ExprSingle |
[35] | IfExpr |
::= | "if" "(" Expr ")" "then"
ExprSingle "else" ExprSingle |
[36] | OrExpr |
::= | AndExpr ( "or" AndExpr )* |
[37] | AndExpr |
::= | CastableExpr (
"and" CastableExpr
)* |
[38] | CastableExpr |
::= | CastExpr ( "castable"
"as" SingleType )? |
[39] | CastExpr |
::= | ValueExpr ( "cast"
"as" SingleType )? |
[40] | ValueExpr |
::= | ValidateExpr |
StepExpr | ExtensionExpr |
[41] | ValidateExpr |
::= | "validate" ValidationMode? "{" Expr "}" |
[42] | ValidationMode |
::= | "lax" | "strict" |
[43] | ExtensionExpr |
::= | Pragma+ "{" Expr? "}" |
[44] | Pragma |
::= | "(#" S? QName (S PragmaContents)? "#)" |
[45] | PragmaContents |
::= | (Char* - (Char* '#)'
Char*)) |
[46] | StepExpr |
::= | PrimaryExpr |
AxisStep |
[47] | AxisStep |
::= | ReverseStep |
ForwardStep |
[48] | ForwardStep |
::= | ForwardAxis NodeTest |
[49] | ForwardAxis |
::= | ("child" "::") |
[50] | ReverseStep |
::= | ReverseAxis NodeTest |
[51] | ReverseAxis |
::= | ("parent" "::") |
[52] | NodeTest |
::= | KindTest | NameTest |
[53] | NameTest |
::= | QName | Wildcard |
[54] | Wildcard |
::= | "*" |
[55] | PrimaryExpr |
::= | Literal | VarRef | ParenthesizedExpr | FunctionCall | OrderedExpr | UnorderedExpr | Constructor |
[56] | Literal |
::= | NumericLiteral |
StringLiteral |
[57] | NumericLiteral |
::= | IntegerLiteral |
DecimalLiteral | DoubleLiteral |
[58] | VarRef |
::= | "$" VarName |
[59] | VarName |
::= | QName |
[60] | ParenthesizedExpr |
::= | "(" Expr? ")" |
[61] | OrderedExpr |
::= | "ordered" "{" Expr
"}" |
[62] | UnorderedExpr |
::= | "unordered" "{" Expr
"}" |
[63] | FunctionCall |
::= | QName "(" (ExprSingle ("," ExprSingle)*)? ")" |
[64] | Constructor |
::= | ComputedConstructor |
[65] | ComputedConstructor |
::= | CompDocConstructor |
[66] | CompDocConstructor |
::= | "document" "{" Expr
"}" |
[67] | CompElemConstructor |
::= | "element" (QName | ("{"
Expr "}")) "{" ContentExpr "}" "{" LocalNamespaceDecls
"}" |
[68] | LocalNamespaceDecl |
::= | "namespace" NCName "{"
URILiteral "}" |
[69] | ContentExpr |
::= | Expr |
[70] | CompAttrConstructor |
::= | "attribute" (QName | ("{"
Expr "}")) "{" Expr "}" |
[71] | CompTextConstructor |
::= | "text" "{" Expr
"}" |
[72] | CompCommentConstructor |
::= | "comment" "{" Expr
"}" |
[73] | CompPIConstructor |
::= | "processing-instruction" (NCName | ("{" Expr "}")) "{" Expr? "}" |
[74] | SingleType |
::= | AtomicType
"?"? |
[75] | TypeDeclaration |
::= | "as" SequenceType |
[76] | SequenceType |
::= | ("empty-sequence" "(" ")") |
[77] | OccurrenceIndicator |
::= | "?" | "*" | "+" |
[78] | ItemType |
::= | KindTest | ("item" "("
")") | AtomicType |
[79] | AtomicType |
::= | QName |
[80] | KindTest |
::= | DocumentTest |
[81] | AnyKindTest |
::= | "node" "(" ")" |
[82] | DocumentTest |
::= | "document-node" "(" (ElementTest | SchemaElementTest)?
")" |
[83] | TextTest |
::= | "text" "(" ")" |
[84] | CommentTest |
::= | "comment" "(" ")" |
[85] | PITest |
::= | "processing-instruction" "(" (NCName | StringLiteral)? ")" |
[86] | AttributeTest |
::= | "attribute" "(" (AttribNameOrWildcard (","
TypeName)?)? ")" |
[87] | AttribNameOrWildcard |
::= | AttributeName |
"*" |
[88] | SchemaAttributeTest |
::= | "schema-attribute" "(" AttributeDeclaration
")" |
[89] | AttributeDeclaration |
::= | AttributeName |
[90] | ElementTest |
::= | "element" "(" (ElementNameOrWildcard (","
TypeName "?"?)?)? ")" |
[91] | ElementNameOrWildcard |
::= | ElementName |
"*" |
[92] | SchemaElementTest |
::= | "schema-element" "(" ElementDeclaration
")" |
[93] | ElementDeclaration |
::= | ElementName |
[94] | AttributeName |
::= | QName |
[95] | ElementName |
::= | QName |
[96] | TypeName |
::= | QName |
[97] | URILiteral |
::= | StringLiteral |
[98] | LocalNamespaceDecls |
::= | LocalNamespaceDecl* |
[113] | Digits |
::= | [0-9]+ |
The following grammar uses the same Basic EBNF notation as [XML], except that grammar symbols always have initial capital letters. The EBNF contains the lexemes embedded in the productions.
[96] | HexDigits |
::= | [0-9a-fA-F]+ |
[97] | CharRef |
::= | "&#" (Digits | ("x"
HexDigits)) ";" |
[98] | Char |
::= | #x0009#x000D#x000A#x0020-#xFFFD |
[1] | AtomicValueContent |
::= | String |
[2] | TypeAnnotation |
::= | "of" "type" TypeName |
[3] | ElementName |
::= | QName |
[4] | ElementNameOrWildcard |
::= | QName | "*" |
[5] | AttributeNameOrWildcard |
::= | QName | "*" |
[6] | AttributeName |
::= | QName |
[7] | Value |
::= | Item |
[8] | SimpleValue |
::= | AtomicValue |
[9] | ElementValue |
::= | "element" ElementName
"nilled"? TypeAnnotation? "{"
Value "}" ("{" NamespaceBindings
"}")? |
[10] | AttributeValue |
::= | "attribute" AttributeName TypeAnnotation? "{" SimpleValue "}" |
[11] | DocumentValue |
::= | "document" "{" Value
"}" |
[12] | TextValue |
::= | "text" "{" String "}" |
[13] | CommentValue |
::= | "comment" "{" String "}" |
[14] | ProcessingInstructionValue |
::= | "processing-instruction" NCName "{" String "}" |
[15] | NamespaceBindings |
::= | NamespaceBinding
("," NamespaceBinding)* |
[16] | LocationHints |
::= | "at" URILiteral (","
URILiteral)* |
[17] | NamespaceBinding |
::= | "namespace" NCName "{"
AnyURI "}" |
[18] | Prefix |
::= | NCName |
[19] | LocalPart |
::= | NCName |
[20] | NodeValue |
::= | ElementValue |
[21] | Item |
::= | NodeValue |
[22] | AtomicValue |
::= | AtomicValueContent TypeAnnotation? |
[23] | TypeName |
::= | QName |
[24] | Type |
::= | FormalItemType |
[25] | FormalItemType |
::= | AtomicTypeName |
NodeType |
[26] | NodeType |
::= | DocumentType |
[27] | ElementContentType |
::= | ElementType |
[28] | AtomicTypeName |
::= | TypeName |
[29] | ElementType |
::= | "element" ElementNameOrWildcard OptTypeSpecifier |
[30] | TypeSpecifier |
::= | OptNillable TypeReference |
[31] | AttributeType |
::= | "attribute" AttributeNameOrWildcard
OptTypeReference |
[32] | Nillable |
::= | "nillable" |
[33] | TypeDerivation |
::= | ComplexTypeDerivation |
AtomicTypeDerivation |
[34] | ComplexTypeDerivation |
::= | OptDerivation
OptMixed "{" Type? "}" |
[35] | AtomicTypeDerivation |
::= | "restricts" AtomicTypeName |
[36] | TypeReference |
::= | "of" "type" TypeName |
[37] | Derivation |
::= | ("restricts" TypeName) |
[38] | Mixed |
::= | "mixed" |
[39] | Definition |
::= | ("define" "element" ElementName OptSubstitution OptNillable TypeReference) |
[40] | Definitions |
::= | (Definition Separator Definitions)? |
[41] | Substitution |
::= | "substitutes" "for" ElementName |
[42] | AttributeModel |
::= | AttributeType |
[43] | ElementModel |
::= | ElementType |
[44] | PrimeType |
::= | FormalItemType |
[45] | DocumentType |
::= | "document" ("{" Type
"}")? |
[46] | SPragma |
::= | ("include" | "import" | "redefine" |
"annotation")* |
[47] | Content |
::= | (("simpleType" | "complexType" | "element" | "attribute"
| "attributeGroup" | "group" | "notation")
"annotation"*)* |
[48] | MixedAttribute |
::= | "mixed" "=" Boolean |
[49] | NillableAttribute |
::= | "nillable" "=" Boolean |
[50] | substitutionGroupAttribute |
::= | "substitutionGroup" "=" QName |
[51] | maxLength |
::= | "maxLength" "=" "nonNegativeInteger" |
[52] | minLength |
::= | "minLength" "=" "nonNegativeInteger" |
[53] | length |
::= | "length" "=" "nonNegativeInteger" |
[54] | maxOccurs |
::= | "maxOccurs" "=" ("nonNegativeInteger" |
"unbounded") |
[55] | minOccurs |
::= | "minOccurs" "=" "nonNegativeInteger" |
[56] | OccursAttributes |
::= | maxOccurs | minOccurs | maxLength | minLength | length |
[57] | ComplexTypeContent |
::= | "annotation"? ("simpleContent" | "complexContent" |
(ChildrenContent AttributeContent)) |
[58] | ChildrenContent |
::= | ("group" | "all" | "choice" | "sequence")? |
[59] | GroupComponent |
::= | "element" | "group" | "choice" | "sequence" |
"any" |
[60] | AttributeContent |
::= | ("attribute" | "attributeGroup")*
"anyAttribute"? |
[61] | UseAttribute |
::= | "use" "=" ("optional" | "prohibited" |
"required") |
[62] | DefaultAttribute |
::= | "default" "=" String |
[63] | FixedAttribute |
::= | "fixed" "=" String |
[64] | PrincipalNodeKind |
::= | "element" | "attribute" | "namespace" |
[65] | FormalFLWORClause |
::= | ForClause | LetClause | WhereClause | OrderByClause |
[66] | FormalReturnClause |
::= | FormalFLWORExpr |
("return" Expr) |
[67] | FormalFLWORExpr |
::= | FormalFLWORClause FormalReturnClause |
[68] | FormalCaseClauses |
::= | (FormalCaseClause
FormalCaseClauses) |
FormalDefaultCaseClause |
[69] | FormalCaseClause |
::= | "case" "$" VarName "as"
SequenceType "return" Expr |
[70] | FormalDefaultCaseClause |
::= | "default" "$" VarName
"return" Expr |
[71] | PrologDeclList |
::= | (PrologDecl Separator PrologDeclList)? |
[72] | PrologDecl |
::= | DefaultCollationDecl |
[73] | OptAtomicType |
::= | AtomicTypeName |
(AtomicTypeName "?") |
"empty" |
[74] | OptMixed |
::= | Mixed? |
[75] | OptNillable |
::= | Nillable? |
[76] | OptSubstitution |
::= | Substitution? |
[77] | OptTypeSpecifier |
::= | TypeSpecifier? |
[78] | OptTypeReference |
::= | TypeReference? |
[79] | OptTypeDeclaration |
::= | TypeDeclaration? |
[80] | OptPositionalVar |
::= | PositionalVar? |
[81] | OptVarName |
::= | ("$" VarName)? |
[82] | OptLocationHints |
::= | LocationHints? |
[83] | ElementContentUnit |
::= | DirectConstructor | EnclosedExpr | DirCharsUnit |
[84] | DirCharsUnit |
::= | (CDataSection |
PredefinedEntityRef |
CharRef | "{{" | "}}" | ElementContentChar)+ |
[85] | FunctionSig |
::= | "declare" "function" expanded-QName "(" TypeList? ")" "as" Type |
[86] | TypeList |
::= | Type ("," Type)* |
[87] | AttributeContentUnits |
::= | AttributeContentUnit* |
[88] | AttributeContentUnit |
::= | AttributeCharsUnit | EnclosedExpr |
[89] | ConstructionMode |
::= | "preserve" | "strip" |
[90] | Axis |
::= | ForwardAxis |
ReverseAxis |
[91] | AttributeCharsUnit |
::= | (QuotAttrContentChar |
AposAttrContentChar |
EscapeQuot | EscapeApos | PredefinedEntityRef |
CharRef | "{{" |
"}}")+ |
[92] | FunctionKey |
::= | expanded-QName "," Arity |
[93] | ProcessingInstructionType |
::= | "processing-instruction" PITargetOrWildcard |
[94] | PITargetOrWildcard |
::= | NCName | "*" |
[95] | OptDerivation |
::= | Derivation? |
Here is the list of the judgments defined in this specification.
Main judgments:
Auxiliary judgments:
statEnv |- (AnyURI | #MAIN) =>module_statEnv statEnv
statEnv |- (AnyURI | #MAIN) =>module_dynEnv dynEnv
statEnv1 |- PrologDeclList =>stat statEnv2 with PrologDeclList1
dynEnv1 ; AnyURI |- (FunctionKey1,FunctionSig1) ... (FunctionKeyn,FunctionSign) =>import_functions dynEnv2
dynEnv1 ; AnyURI |- (expanded-QName1, Type1), ···, (expanded-QNamen, Typen) =>import_variables dynEnv2
statEnv |- OptMixed Type1 adjusts to Type2
dynEnv |- Value can be cast to SingleType
dynEnv1 extended with dynamic environment dynEnv2 yields dynEnv3 for uri AnyURI
statEnv1 extended with static environment statEnv2 yields statEnv3 for uri AnyURI
statEnv |- function declaration FunctionDecl with signature FunctionSig : Typer
dynEnv |- function expanded-QName with types (Type1,...,Typen) on values (Value1,...,Valuen) yields Value
dynEnv |- LiteralExpr has atomic value AtomicValue
statEnv |- Type1 has node content Type2
Axis has principal PrincipalNodeKind
AnyURI is target namespace of modules Module1 ... Modulen
statEnv |- ElementName name lookup ElementType yields OptNillable TypeReference
statEnv |- AttributeName name lookup AttributeType yields TypeReference
statEnv |- nil-annotate as Nillable? Type ( Value1 ) => Value2
statEnv |- QName of attr expands to expanded-QName
statEnv |- QName of elem/type expands to expanded-QName
statEnv |- QName of func expands to expanded-QName
statEnv |- QName of var expands to Variable
expanded-QName operator type for AtomicType1 and AtomicType2 is AtomicType3
statEnv |- OptMixed Type1 opt-mixes to Type2
statEnv |- TypeReference resolves to TypeName { Type }
second argument contribution for sum with Type1 and Type2 is Type3
statEnv |- simply annotate as SimpleType ( SimpleValue ) => SimpleValue2
statEnv |- SimpleValue simply erases to String
statEnv |- ElementType type lookup OptNillable TypeReference
statEnv |- test NodeTest with PrincipalNodeKind of Type1 : Type2
dynEnv |- test NodeTest with PrincipalNodeKind of Value1 => Value2
statEnv |- type definitions derived from TypeName are Definition1 ... Definitionn
statEnv |- ElementNameOrWildcard with mode ValidationMode resolves to Type
Here is the list of functions from the [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)] document that are used in the [XPath/XQuery] Formal Semantics:
This section gives the semantics specific to overloaded internal functions (with prefix fs:) that are used to define overloaded XQuery operators (with prefix op:), such as comparison expressions or arithmetic expressions. Static typing for those functions are defined over unions of (possibly optional) atomic types. The semantics is obtained in three steps. First, a rule is applied to deal with the union of those (possibly optional) atomic types. A second set of rules treat the cases where one of the operands of those functions is the empty type (resp. empty sequence) or optional. Finally, a final rule deals with type promotion and access to an operators mapping table which maps the overloaded internal functions to the appropriate operator functions defined in [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)] and give the corresponding type.
Notation
The following auxiliary grammar production describe optional atomic types.
[73 (Formal)] | OptAtomicType |
::= | AtomicTypeName |
(AtomicTypeName "?") |
"empty" |
The following static typing rules apply generically to all the fs: special functions. They do not apply to any other function calls, which are treated in [4.1.5 Function Calls].
First, if the static type of one or several of the expressions passed as argument is a union of atomic types, the function call is type checked once separately for each atomic type in that union. The static type of the entire function call expression is then the union of the types computed in each case.
|
|||||||
|
|||||||
|
Note
Note that this approach can be used since the type declared for a function parameter is never itself be a union.
The following rules deal with optional arguments. In the case of binary operators, if either one of the types of the operands is empty, the resulting type is empty.
If either one of the types of the operands is optional, the type obtained by propagating the optional occurrence indicator.
|
||||
|
||||
statEnv |- expanded-QName(Type1,Type2) : AtomicType3? |
|
||||
|
||||
statEnv |- expanded-QName(Type1,Type2) : AtomicType3? |
|
||||
|
||||
statEnv |- expanded-QName(Type1,Type2) : AtomicType3? |
In the case of unary operators, if the type of the operand is empty, the resulting type is empty.
|
||
|
||
statEnv |- expanded-QName(Type1) : empty |
Finally, the resulting type is obtained by performing type promotion and accessing the operators mapping table (using the operator type for judgment defined below).
|
||||
|
||||
|
|
|||
|
|||
|
Each fs:
overloaded operator maps to the
corresponding equivalent overloaded op:
operator, as
defined in [XQuery 1.0 and XPath 2.0
Functions and Operators (Second Edition)], and deals with the
case where one of the operands is the empty sequence.
The dynamic semantics of the fs:
operator is
similar to using the following user-defined function.
declare function fs:opname($x1 as
xs:anyAtomicType?, $x2 as xs:anyAtomicType?) as xs:anyAtomicType?
{ |
if (fn:empty($x1) or fn:empty($x2)) then ()
else [fs:opname($x1,$x2)]OverloadedOp |
}; |
Where [fs:opname()]OverloadedOp maps to the corresponding op: operator in [XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition)], as defined in the table below.
Notation
The operators mapping table is given below. The table is used to define the following auxiliary mapping rules and judgments.
The mapping rule for binary and unary operators
and
where the operator depends on the type of each value returned by Expr1 and Expr2.
The judgments for binary and unary operators
and
hold when the operator table indicates that the operator expanded-QName has the output type AtomicType3 for the input types AtomicType1 and AtomicType2.
Note that in the following table, all numeric functions are applied to operands with the same type. Values are promoted to compatible types using the function call semantics given in [4.1.5 Function Calls].
Gregorian refers to the types xs:gYearMonth
,
xs:gYear
, xs:gMonthDay
,
xs:gDay
, and xs:gMonth
. For binary
operators that accept two Gregorian-type operands, both operands
must have the same type (for example, if one operand is of type
xs:gDay
, the other operand must be of type
xs:gDay
.)
Internal Function | AtomicType1 | AtomicType2 | Denotes | AtomicType3 |
---|---|---|---|---|
fs:plus (A, B) |
xs:integer |
xs:integer |
op:numeric-add(A, B) | xs:integer |
fs:plus (A, B) |
xs:decimal |
xs:decimal |
op:numeric-add(A, B) | xs:decimal |
fs:plus (A, B) |
xs:float |
xs:float |
op:numeric-add(A, B) | xs:float |
fs:plus (A, B) |
xs:double |
xs:double |
op:numeric-add(A, B) | xs:double |
fs:plus (A, B) |
xs:date |
xs:yearMonthDuration |
op:add-yearMonthDuration-to-date(A, B) | xs:date |
fs:plus (A, B) |
xs:yearMonthDuration |
xs:date |
op:add-yearMonthDuration-to-date(B, A) | xs:date |
fs:plus (A, B) |
xs:date |
xs:dayTimeDuration |
op:add-dayTimeDuration-to-date(A, B) | xs:date |
fs:plus (A, B) |
xs:dayTimeDuration |
xs:date |
op:add-dayTimeDuration-to-date(B, A) | xs:date |
fs:plus (A, B) |
xs:time |
xs:dayTimeDuration |
op:add-dayTimeDuration-to-time(A, B) | xs:time |
fs:plus (A, B) |
xs:dayTimeDuration |
xs:time |
op:add-dayTimeDuration-to-time(B, A) | xs:time |
fs:plus (A, B) |
xs:dateTime |
xs:yearMonthDuration |
op:add-yearMonthDuration-to-dateTime(A, B) | xs:dateTime |
fs:plus (A, B) |
xs:yearMonthDuration |
xs:dateTime |
op:add-yearMonthDuration-to-dateTime(B, A) | xs:dateTime |
fs:plus (A, B) |
xs:dateTime |
xs:dayTimeDuration |
op:add-dayTimeDuration-to-dateTime(A, B) | xs:dateTime |
fs:plus (A, B) |
xs:dayTimeDuration |
xs:dateTime |
op:add-dayTimeDuration-to-dateTime(B, A) | xs:dateTime |
fs:plus (A, B) |
xs:yearMonthDuration |
xs:yearMonthDuration |
op:add-yearMonthDurations(A, B) | xs:yearMonthDuration |
fs:plus (A, B) |
xs:dayTimeDuration |
xs:dayTimeDuration |
op:add-dayTimeDurations(A, B) | xs:dayTimeDuration |
fs:minus (A, B) |
xs:integer |
xs:integer |
op:numeric-subtract(A, B) | xs:integer |
fs:minus (A, B) |
xs:decimal |
xs:decimal |
op:numeric-subtract(A, B) | xs:decimal |
fs:minus (A, B) |
xs:float |
xs:float |
op:numeric-subtract(A, B) | xs:float |
fs:minus (A, B) |
xs:double |
xs:double |
op:numeric-subtract(A, B) | xs:double |
fs:minus (A, B) |
xs:date |
xs:date |
op:subtract-dates(A, B) | xs:dayTimeDuration |
fs:minus (A, B) |
xs:date |
xs:yearMonthDuration |
op:subtract-yearMonthDuration-from-date(A, B) | xs:date |
fs:minus (A, B) |
xs:date |
xs:dayTimeDuration |
op:subtract-dayTimeDuration-from-date(A, B) | xs:date |
fs:minus (A, B) |
xs:time |
xs:time |
op:subtract-times(A, B) | xs:dayTimeDuration |
fs:minus (A, B) |
xs:time |
xs:dayTimeDuration |
op:subtract-dayTimeDuration-from-time(A, B) | xs:time |
fs:minus (A, B) |
xs:dateTime |
xs:dateTime |
op:subtract-dateTimes(A, B) | xs:dayTimeDuration |
fs:minus (A, B) |
xs:dateTime |
xs:yearMonthDuration |
op:subtract-yearMonthDuration-from-dateTime(A, B) | xs:dateTime |
fs:minus (A, B) |
xs:dateTime |
xs:dayTimeDuration |
op:subtract-dayTimeDuration-from-dateTime(A, B) | xs:dateTime |
fs:minus (A, B) |
xs:yearMonthDuration |
xs:yearMonthDuration |
op:subtract-yearMonthDurations(A, B) | xs:yearMonthDuration |
fs:minus (A, B) |
xs:dayTimeDuration |
xs:dayTimeDuration |
op:subtract-dayTimeDurations(A, B) | xs:dayTimeDuration |
fs:times (A, B) |
xs:integer |
xs:integer |
op:numeric-multiply(A, B) | xs:integer |
fs:times (A, B) |
xs:decimal |
xs:decimal |
op:numeric-multiply(A, B) | xs:decimal |
fs:times (A, B) |
xs:float |
xs:float |
op:numeric-multiply(A, B) | xs:float |
fs:times (A, B) |
xs:double |
xs:double |
op:numeric-multiply(A, B) | xs:double |
fs:times (A, B) |
xs:yearMonthDuration |
xs:double |
op:multiply-yearMonthDuration(A, B) | xs:yearMonthDuration |
fs:times (A, B) |
xs:double |
xs:yearMonthDuration |
op:multiply-yearMonthDuration(B, A) | xs:yearMonthDuration |
fs:times (A, B) |
xs:dayTimeDuration |
xs:double |
op:multiply-dayTimeDuration(A, B) | xs:dayTimeDuration |
fs:times (A, B) |
xs:double |
xs:dayTimeDuration |
op:multiply-dayTimeDuration(B, A) | xs:dayTimeDuration |
fs:idiv (A, B) |
xs:integer |
xs:integer |
op:numeric-integer-divide(A, B) | xs:integer |
fs:idiv (A, B) |
xs:decimal |
xs:decimal |
op:numeric-integer-divide(A, B) | xs:integer |
fs:idiv (A, B) |
xs:float |
xs:float |
op:numeric-integer-divide(A, B) | xs:integer |
fs:idiv (A, B) |
xs:double |
xs:double |
op:numeric-integer-divide(A, B) | xs:integer |
fs:div (A, B) |
xs:integer |
xs:integer |
op:numeric-divide(A, B) | xs:decimal |
fs:div (A, B) |
xs:decimal |
xs:decimal |
op:numeric-divide(A, B) | xs:decimal |
fs:div (A, B) |
xs:float |
xs:float |
op:numeric-divide(A, B) | xs:float |
fs:div (A, B) |
xs:double |
xs:double |
op:numeric-divide(A, B) | xs:double |
fs:div (A, B) |
xs:yearMonthDuration |
xs:double |
op:divide-yearMonthDuration(A, B) | xs:yearMonthDuration |
fs:div (A, B) |
xs:dayTimeDuration |
xs:double |
op:divide-dayTimeDuration(A, B) | xs:dayTimeDuration |
fs:div (A, B) |
xs:yearMonthDuration |
xs:yearMonthDuration |
op:divide-yearMonthDuration-by-yearMonthDuration(A, B) | xs:decimal |
fs:div (A, B) |
xs:dayTimeDuration |
xs:dayTimeDuration |
op:divide-dayTimeDuration-by-dayTimeDuration(A, B) | xs:decimal |
fs:mod (A, B) |
xs:integer |
xs:integer |
op:numeric-mod(A, B) | xs:integer |
fs:mod (A, B) |
xs:decimal |
xs:decimal |
op:numeric-mod(A, B) | xs:decimal |
fs:mod (A, B) |
xs:float |
xs:float |
op:numeric-mod(A, B) | xs:float |
fs:mod (A, B) |
xs:double |
xs:double |
op:numeric-mod(A, B) | xs:double |
fs:eq (A, B) |
xs:integer |
xs:integer |
op:numeric-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:decimal |
xs:decimal |
op:numeric-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:float |
xs:float |
op:numeric-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:double |
xs:double |
op:numeric-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:boolean |
xs:boolean |
op:boolean-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:string |
xs:string |
op:numeric-equal(fn:compare(A, B), 0) | xs:boolean |
fs:eq (A, B) |
xs:date |
xs:date |
op:date-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:time |
xs:time |
op:time-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:dateTime |
xs:dateTime |
op:dateTime-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:duration |
xs:duration |
op:duration-equal(A, B) | xs:boolean |
fs:eq (A, B) |
Gregorian | Gregorian | op:gYear-equal(A, B) etc. | xs:boolean |
fs:eq (A, B) |
xs:hexBinary |
xs:hexBinary |
op:hexBinary-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:base64Binary |
xs:base64Binary |
op:base64Binary-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:anyURI |
xs:anyURI |
op:numeric-equal(fn:compare(A, B), 0) | xs:boolean |
fs:eq (A, B) |
xs:QName |
xs:QName |
op:QName-equal(A, B) | xs:boolean |
fs:eq (A, B) |
xs:NOTATION |
xs:NOTATION |
op:NOTATION-equal(A, B) | xs:boolean |
fs:ne (A, B) |
xs:integer |
xs:integer |
fn:not (op:numeric-equal(A, B)) |
xs:boolean |
fs:ne (A, B) |
xs:decimal |
xs:decimal |
fn:not (op:numeric-equal(A, B)) |
xs:boolean |
fs:ne (A, B) |
xs:float |
xs:float |
fn:not (op:numeric-equal(A, B)) |
xs:boolean |
fs:ne (A, B) |
xs:double |
xs:double |
fn:not (op:numeric-equal(A, B)) |
xs:boolean |
fs:ne (A, B) |
xs:boolean |
xs:boolean |
fn:not (op:boolean-equal(A, B)) |
xs:boolean |
fs:ne (A, B) |
xs:string |
xs:string |
fn:not (op:numeric-equal(fn:compare(A, B),
0)) |
xs:boolean |
fs:ne (A, B) |
xs:date |
xs:date |
fn:not (op:date-equal(A, B)) |
xs:boolean |
fs:ne (A, B) |
xs:time |
xs:time |
fn:not (op:time-equal(A, B)) |
xs:boolean |
fs:ne (A, B) |
xs:dateTime |
xs:dateTime |
fn:not (op:dateTime-equal(A,
B)) |
xs:boolean |
fs:ne (A, B) |
xs:duration |
xs:duration |
fn:not (op:duration-equal(A,
B)) |
xs:boolean |
fs:ne (A, B) |
Gregorian | Gregorian | fn:not (op:gYear-equal(A, B))
etc. |
xs:boolean |
fs:ne (A, B) |
xs:hexBinary |
xs:hexBinary |
fn:not (op:hexBinary-equal(A,
B)) |
xs:boolean |
fs:ne (A, B) |
xs:base64Binary |
xs:base64Binary |
fn:not (op:base64Binary-equal(A,
B)) |
xs:boolean |
fs:ne (A, B) |
xs:anyURI |
xs:anyURI |
fn:not (op:numeric-equal(fn:compare(A, B),
0)) |
xs:boolean |
fs:ne (A, B) |
xs:QName |
xs:QName |
fn:not (op:QName-equal(A, B)) |
xs:boolean |
fs:ne (A, B) |
xs:NOTATION |
xs:NOTATION |
fn:not (op:NOTATION-equal(A,
B)) |
xs:boolean |
fs:gt (A, B) |
xs:integer |
xs:integer |
op:numeric-greater-than(A, B) | xs:boolean |
fs:gt (A, B) |
xs:decimal |
xs:decimal |
op:numeric-greater-than(A, B) | xs:boolean |
fs:gt (A, B) |
xs:float |
xs:float |
op:numeric-greater-than(A, B) | xs:boolean |
fs:gt (A, B) |
xs:double |
xs:double |
op:numeric-greater-than(A, B) | xs:boolean |
fs:gt (A, B) |
xs:boolean |
xs:boolean |
op:boolean-greater-than(A, B) | xs:boolean |
fs:gt (A, B) |
xs:string |
xs:string |
op:numeric-greater-than(fn:compare (A, B),
0) |
xs:boolean |
fs:gt (A, B) |
xs:date |
xs:date |
op:date-greater-than(A, B) | xs:boolean |
fs:gt (A, B) |
xs:time |
xs:time |
op:time-greater-than(A, B) | xs:boolean |
fs:gt (A, B) |
xs:dateTime |
xs:dateTime |
op:dateTime-greater-than(A, B) | xs:boolean |
fs:gt (A, B) |
xs:yearMonthDuration |
xs:yearMonthDuration |
op:yearMonthDuration-greater-than(A, B) | xs:boolean |
fs:gt (A, B) |
xs:dayTimeDuration |
xs:dayTimeDuration |
op:dayTimeDuration-greater-than(A, B) | xs:boolean |
fs:lt (A, B) |
xs:integer |
xs:integer |
op:numeric-less-than(A, B) | xs:boolean |
fs:lt (A, B) |
xs:decimal |
xs:decimal |
op:numeric-less-than(A, B) | xs:boolean |
fs:lt (A, B) |
xs:float |
xs:float |
op:numeric-less-than(A, B) | xs:boolean |
fs:lt (A, B) |
xs:double |
xs:double |
op:numeric-less-than(A, B) | xs:boolean |
fs:lt (A, B) |
xs:boolean |
xs:boolean |
op:boolean-less-than(A, B) | xs:boolean |
fs:lt (A, B) |
xs:string |
xs:string |
op:numeric-less-than(fn:compare (A, B),
0) |
xs:boolean |
fs:lt (A, B) |
xs:date |
xs:date |
op:date-less-than(A, B) | xs:boolean |
fs:lt (A, B) |
xs:time |
xs:time |
op:time-less-than(A, B) | xs:boolean |
fs:lt (A, B) |
xs:dateTime |
xs:dateTime |
op:dateTime-less-than(A, B) | xs:boolean |
fs:lt (A, B) |
xs:yearMonthDuration |
xs:yearMonthDuration |
op:yearMonthDuration-less-than(A, B) | xs:boolean |
fs:lt (A, B) |
xs:dayTimeDuration |
xs:dayTimeDuration |
op:dayTimeDuration-less-than(A, B) | xs:boolean |
fs:ge (A, B) |
xs:integer |
xs:integer |
op:numeric-greater-than(A, B) or op:numeric-equal(A,B) | xs:boolean |
fs:ge (A, B) |
xs:decimal |
xs:decimal |
op:numeric-greater-than(A, B) or op:numeric-equal(A,B) | xs:boolean |
fs:ge (A, B) |
xs:float |
xs:float |
op:numeric-greater-than(A, B) or op:numeric-equal(A,B) | xs:boolean |
fs:ge (A, B) |
xs:double |
xs:double |
op:numeric-greater-than(A, B) or op:numeric-equal(A,B) | xs:boolean |
fs:ge (A, B) |
xs:boolean |
xs:boolean |
op:numeric-greater-than(A, B) or op:numeric-equal(A,B) | xs:boolean |
fs:ge (A, B) |
xs:string |
xs:string |
op:numeric-greater-than(fn:compare (A, B),
-1) |
xs:boolean |
fs:ge (A, B) |
xs:date |
xs:date |
op:date-less-than(B, A) | xs:boolean |
fs:ge (A, B) |
xs:time |
xs:time |
op:time-less-than(B, A) | xs:boolean |
fs:ge (A, B) |
xs:dateTime |
xs:dateTime |
op:dateTime-less-than(B, A) | xs:boolean |
fs:ge (A, B) |
xs:yearMonthDuration |
xs:yearMonthDuration |
op:yearMonthDuration-less-than(B, A) | xs:boolean |
fs:ge (A, B) |
xs:dayTimeDuration |
xs:dayTimeDuration |
op:dayTimeDuration-less-than(B, A) | xs:boolean |
fs:le (A, B) |
xs:integer |
xs:integer |
op:numeric-less-than(A, B) or op:numeric-equal(A,B) | xs:boolean |
fs:le (A, B) |
xs:decimal |
xs:decimal |
op:numeric-less-than(A, B) or op:numeric-equal(A,B) | xs:boolean |
fs:le (A, B) |
xs:float |
xs:float |
op:numeric-less-than(A, B) or op:numeric-equal(A,B) | xs:boolean |
fs:le (A, B) |
xs:double |
xs:double |
op:numeric-less-than(A, B) or op:numeric-equal(A,B) | xs:boolean |
fs:le (A, B) |
xs:boolean |
xs:boolean |
op:numeric-less-than(A, B) or op:numeric-equal(A,B) | xs:boolean |
fs:le (A, B) |
xs:string |
xs:string |
op:numeric-less-than(fn:compare (A, B),
1) |
xs:boolean |
fs:le (A, B) |
xs:date |
xs:date |
op:date-greater-than(B, A) | xs:boolean |
fs:le (A, B) |
xs:time |
xs:time |
op:time-greater-than(B, A) | xs:boolean |
fs:le (A, B) |
xs:dateTime |
xs:dateTime |
op:dateTime-greater-than(B, A) | xs:boolean |
fs:le (A, B) |
xs:yearMonthDuration |
xs:yearMonthDuration |
op:yearMonthDuration-greater-than(B, A) | xs:boolean |
fs:le (A, B) |
xs:dayTimeDuration |
xs:dayTimeDuration |
op:dayTimeDuration-greater-than(B, A) | xs:boolean |
fs:is-same-node (A, B) |
node() | node() | op:is-same-node |
xs:boolean |
fs:node-before (A, B) |
node() | node() | op:node-before |
xs:boolean |
fs:node-after (A, B) |
node() | node() | op:node-after |
xs:boolean |
Internal Function | AtomicType1 | Denotes | AtomicType3 |
---|---|---|---|
fs:unary-plus (A) |
xs:integer |
op:numeric-unary-plus(A) | xs:integer |
fs:unary-plus (A) |
xs:decimal |
op:numeric-unary-plus(A) | xs:decimal |
fs:unary-plus (A) |
xs:float |
op:numeric-unary-plus(A) | xs:float |
fs:unary-plus (A) |
xs:double |
op:numeric-unary-plus(A) | xs:double |
fs:unary-minus (A) |
xs:integer |
op:numeric-unary-minus(A) | xs:integer |
fs:unary-minus (A) |
xs:decimal |
op:numeric-unary-minus(A) | xs:decimal |
fs:unary-minus (A) |
xs:float |
op:numeric-unary-minus(A) | xs:float |
fs:unary-minus (A) |
xs:double |
op:numeric-unary-minus(A) | xs:double |
This section describes how XML Schema declarations, as specified by XML Schema are imported into the [XPath/XQuery] type system.
During schema import processing, the [XPath/XQuery] environment imports XML Schema declarations and loads them as declarations in the [XPath/XQuery] type system. The semantics of that loading process is defined by normalization rules that map XML Schema descriptions into the [XPath/XQuery] type system.
Here is summarized the XML Schema features which are covered by the formal semantics, and handled by the import mapping described in this section. For each feature, the following indications are used.
Handled indicates features that are relevant for [XPath/XQuery], are modeled in the [XPath/XQuery] type system, and are supported by the mapping.
Not in v1.0 indicates features that are relevant to [XPath/XQuery], but are not yet modeled in the [XPath/XQuery] type system or are not handled by the mapping in XQuery V1.0. In case the [XPath/XQuery] type system provides appropriate support for those features, but the mapping is incomplete, the additional annotation mapping only is used.
Not handled indicates features that are relevant for [XPath/XQuery], but are not modeled in the [XPath/XQuery] type system, and are not handled by the mapping. Such features are typically only related to validation, for which the formal semantics defines a partial model.
Ignored Indicates features that are not relevant for [XPath/XQuery], are not modeled in the [XPath/XQuery] type system, and are not relevant for the mapping. Such features might have to do with documentation of the schema, or might affect which Schemas are legal, but do not affect which documents match which Schemas.
Here is the exhaustive list of XML Schema features and their status in this document.
Feature: | Supported |
Primitive Simple types | Handled |
Simple type derivation by restriction | Handled |
Derivation by list and union | Handled |
Facets on simple types | Not handled |
ID and IDREF constraints | Ignored |
Attribute Declarations | |
default,fixed,use | Not in v1.0 |
Element Declarations | |
default, fixed (value constraint) | Not in v1.0 |
nillable | Handled |
substitution group affiliation | Handled |
substitution group exclusions | Ignored |
disallowed substitutions | Ignored |
abstract | Not in v1.0 |
Complex Type Definitions | |
derivation by restriction | Handled |
derivation by extension | Handled |
final | Ignored |
abstract | Not in v1.0 |
AttributeUses | |
required | Not in v1.0, mapping only |
default, fixed (value constraint) | Not in v1.0 |
Attribute Group Definitions | Not in v1.0, mapping only |
Model Group Definitions | Not in v1.0, mapping only |
Model Groups | Handled |
Particles | Handled |
Wildcards | |
process contents strict, skip, lax | Ignored |
namespace wild cards. | Ignored |
Identity-constraint Definitions | Ignored |
Notation Declarations | Ignored |
Annotations | Ignored |
Note that the schema import feature specified here assumes it is given a legal schema as input. As a result, it is not necessary to check for 'block' or 'abstract' attributes.
The presentation of the schema mapping is done according to the following organization.
Schema component
First each schema component is summarized using the same notation used in the XML Representation Summary sections in XML Schema. For instance, here is the XML Representation Summary for complex types.
<complexType |
[ ignored ] abstract = boolean : false |
[ ignored ] block = (#all | List of (extension | restriction)) |
[ ignored ] final = (#all | List of (extension | restriction)) |
[ ignored ] id = ID |
mixed = boolean : false |
name = NCName |
[ ignored ] {any schemaAttributes with non-schema namespace ...} > |
Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((schemaAttribute | schemaAttributeGroup)*, anySchemaAttribute?)))) |
</complexType> |
Attributes indicated as [ ignored ] are not mapped into the [XPath/XQuery] type system.
Attributes indicated as [ not handled ] are not currently handled by the mapping.
Note that in order to simplify the mapping, it is assumed that
the default values for all attributes in the XML Representation of
Schema are filled in. For instance in the above complex type, if
the mixed
attribute is not present, it will be treated
as being present and having the value "false"
.
Schema mapping
XML Schema import is specified by means of mapping rules. All mapping rules have the structure below.
[SchemaComponent]Subscript |
== |
TypeComponent |
The SchemaComponent above the horizontal rule denotes an XML Schema component before translation and the TypeComponent beneath the horizontal rule denotes an equivalent type component in the [XPath/XQuery] type system.
Notation
Whenever necessary for the mapping rules, specific grammar productions which describe fragments of XML Schema may be introduced. For instance, here are grammar productions used to describes fragments of the XML Representation Summary for the complexType Element Information Item.
[57 (Formal)] | ComplexTypeContent |
::= | "annotation"? ("simpleContent" | "complexContent" |
(ChildrenContent AttributeContent)) |
[60 (Formal)] | AttributeContent |
::= | ("attribute" | "attributeGroup")*
"anyAttribute"? |
[58 (Formal)] | ChildrenContent |
::= | ("group" | "all" | "choice" | "sequence")? |
As in the rest of this document, some mapping rules may use fragments of the XML Representation corresponding to the syntactic categories defined by those grammar productions. For instance, the following complex type fragment uses the syntactic categories: TypeName, ComplexTypeContent, and AttributeContent, ChildrenContent, and MixedAttribute.
<complexType |
name = TypeName |
MixedAttribute > |
ChildrenContent AttributeContent |
</complexType> |
Notation
The normalization rule
[Schema]Schema |
== |
Definitions |
maps a complete schema into a set of Definitions in the [XPath/XQuery] type system.
The normalization rule
[SchemaComponent]definition(targetNCName) |
== |
Definition |
maps a top level schema component into a Definition in the [XPath/XQuery] type system, given the target namespace targetAnyURI.
The normalization rule
[SchemaComponent]content(targetNCName) |
== |
TypeComponent |
maps a schema component not directly under the schema element, into a TypeComponent in the [XPath/XQuery] type system, given the target namespace targetAnyURI.
The XML Schema attributes: use, default, fixed, minOccurs, maxOccurs, mixed, nillable, and substitutionGroup, require specific mapping rules.
The "use", "default", and "fixed" attributes are used to describe the occurrence and default behavior of a given attribute.
Notation
The following auxiliary grammar productions are used to describe the "use", "default", and "fixed" attributes.
[61 (Formal)] | UseAttribute |
::= | "use" "=" ("optional" | "prohibited" |
"required") |
[62 (Formal)] | DefaultAttribute |
::= | "default" "=" String |
[63 (Formal)] | FixedAttribute |
::= | "fixed" "=" String |
The normalization rule
[UseAttribute DefaultAttribute? FixedAttribute? ]use |
== |
OccurrenceIndicator |
maps a combination of a use attribute UseAttribute, along with an optional default or fixed attribute in Schema into the occurrence indicator OccurrenceIndicator in the [XPath/XQuery] type system.
Schema mapping
Use attributes are mapped to the type system in the following way. In case there is a default or fixed attribute, the attribute is always present in the PSVI and the use attribute is ignored.
UseAttribute DefaultAttributeuse |
== |
1 |
UseAttribute FixedAttributeuse |
== |
1 |
use = "optional"use |
== |
? |
use = "required"use |
== |
1 |
Editorial note | |
Issue: how derivation of attribute declaration and the "prohibited" use attributes are mapped in the [XPath/XQuery] type system is still an open issue. |
Notation
The following auxiliary grammar productions are used to describe occurrence attributes and the length facets.
[56 (Formal)] | OccursAttributes |
::= | maxOccurs | minOccurs | maxLength | minLength | length |
[54 (Formal)] | maxOccurs |
::= | "maxOccurs" "=" ("nonNegativeInteger" |
"unbounded") |
[55 (Formal)] | minOccurs |
::= | "minOccurs" "=" "nonNegativeInteger" |
[51 (Formal)] | maxLength |
::= | "maxLength" "=" "nonNegativeInteger" |
[52 (Formal)] | minLength |
::= | "minLength" "=" "nonNegativeInteger" |
[53 (Formal)] | length |
::= | "length" "=" "nonNegativeInteger" |
The normalization rule
[OccursAttributes]occurs |
== |
OccurrenceIndicator |
maps the occurrence attributes and facets OccursAttributes in Schema into the occurrence indicator OccurrenceIndicator in the [XPath/XQuery] type system.
Schema mapping
Occurrence attributes are mapped to the type system in the following way.
[minOccurs="0" maxOccurs="1"]occurs |
== |
? |
[minOccurs="1" maxOccurs="1"]occurs |
== |
[minOccurs="0" maxOccurs="n"]occurs |
== |
* |
[minOccurs="1" maxOccurs="n"]occurs |
== |
+ |
where n > 1.
[minOccurs="n" maxOccurs="m"]occurs |
== |
+ |
where m >= n > 1
[minLength="0" maxLength="1"]occurs |
== |
? |
[minLength="1" maxLength="1"]occurs |
== |
[minLength="0" maxLength="n"]occurs |
== |
* |
[minLength="1" maxLength="n"]occurs |
== |
+ |
where n > 1.
[minLength="n" maxLength="m"]occurs |
== |
+ |
where m >= n > 1
[length="1"]occurs |
== |
[length="n"]occurs |
== |
+ |
where n > 1
Notation
The following auxiliary grammar productions are used to describe the "mixed" attribute.
[48 (Formal)] | MixedAttribute |
::= | "mixed" "=" Boolean |
The normalization rule
maps the mixed attribute MixedAttribute in Schema into a Mixed notation in the [XPath/XQuery] type system.
Schema mapping
If the mixed attribute is true it is mapped to a mixed notation in the [XPath/XQuery] type system.
[ mixed = "true" ]mixed |
== |
mixed |
If the mixed attribute is false it is mapped to empty in the [XPath/XQuery] type system.
[ mixed = "false" ]mixed |
== |
Notation
The following auxiliary grammar productions are used to describe the "nillable" attribute.
[49 (Formal)] | NillableAttribute |
::= | "nillable" "=" Boolean |
The normalization rule
maps the nillable attribute NillableAttribute in Schema into a Nillable notation in the [XPath/XQuery] type system.
Schema mapping
If the nillable attribute is true it is mapped to a nillable notation in the [XPath/XQuery] type system.
[ nillable = "true" ]nillable |
== |
nillable |
If the nillable attribute is false it is mapped to empty in the [XPath/XQuery] type system.
[ nillable = "false" ]nillable |
== |
Notation
The substitution group declaration indicates the element that a given element can be substituted for. The following auxiliary grammar productions are used to describe the "substitutionGroup" attribute.
[50 (Formal)] | substitutionGroupAttribute |
::= | "substitutionGroup" "=" QName |
The normalization rule
[substitutionGroupAttribute]substitution |
== |
Substitution |
maps the substitutionGroup attribute substitutionGroupAttribute in Schema into a Substitution notation in the [XPath/XQuery] type system.
Schema mapping
If the substitutionGroup attribute is present, it is mapped to a substitutionGroup notation in the [XPath/XQuery] type system.
[ substitutionGroup = QName ]substitution |
== |
substitutes for QName |
Otherwise, it is mapped to empty.
Notation
As explained in [2.4 The [XPath/XQuery] Type System], the [XPath/XQuery] type uses system-generated type names for anonymous types. For the purpose of this document those type names are generated at XML Schema import time.
Schema component
A schema is represented in XML by the following structure.
<schema |
[ not handled ] attributeFormDefault = (qualified | unqualified) : unqualified |
[ ignored ] blockDefault = (#all | List of (extension | restriction | substitution)) : ' ' |
[ not handled ] elementFormDefault = (qualified | unqualified) : unqualified |
[ ignored ] finalDefault = (#all | List of (extension | restriction)) : ' ' |
[ ignored ] id = ID |
targetNamespace = anyURI |
[ ignored ] version = token |
[ ignored ] xml:lang = language |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: ((include | import | redefine | annotation)*, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*) |
</schema> |
Notation
The following auxiliary grammar productions are used.
[46 (Formal)] | SPragma |
::= | ("include" | "import" | "redefine" |
"annotation")* |
[47 (Formal)] | Content |
::= | (("simpleType" | "complexType" | "element" | "attribute"
| "attributeGroup" | "group" | "notation")
"annotation"*)* |
The auxiliary normalization rule
[Pragma]pragma(targetAnyURI) |
== |
Definitions |
maps the a schema pragma into a set of definitions in the [XPath/XQuery] type system.
Schema mapping
Schemas are imported by the "schema" declaration in the preamble of a query. To import a schema, the document referred to by the given URI is opened and the schema declarations contained in the document are translated into the corresponding in-line type definitions. The mechanism for finding a schema document, possibly using the optional schema location hint, is not specified formally.
[schema StringLiteral (at StringLiteral)?]Schema |
== |
[open-schema-document(StringLiteral (at StringLiteral)?)]Schema |
[
|
||||
== | ||||
[Pragma]pragma(targetAnyURI) [Content]definition(targetNCName) |
Schema component
A schema include is represented in XML by the following structure.
<include |
[ ignored ] id = ID |
schemaLocation = anyURI |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?) |
</include> |
Schema mapping
A schema include is not specified here, and is assumed to be handled by the XML Schema processor.
Schema component
A schema redefinition is represented in XML by the following structure.
<redefine |
[ ignored ] id = ID |
schemaLocation = anyURI |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation | (simpleType | complexType | group | attributeGroup))* |
</redefine> |
Schema mapping
A schema redefine is not specified here, and is assumed to be handled by the XML Schema processor.
Schema component
A schema import is represented in XML by the following structure.
<import |
[ ignored ] id = ID |
namespace = anyURI |
schemaLocation = anyURI |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?) |
</import> |
Schema mapping
A schema import is not specified here, and is assumed to be handled by the XML Schema processor.
Schema component
The following structure describes attribute declarations in XML Schema.
<attribute |
[ not handled ] default = string |
[ not handled ] fixed = string |
[ not handled ] form = (qualified | unqualified) |
[ ignored ] id = ID |
name = NCName |
ref = QName |
type = QName |
use = (optional | prohibited | required) : optional |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (simpleType?)) |
</attribute> |
Schema import distinguishes between global attribute declarations and local attribute declarations.
Schema mapping
Global attribute declarations are mapped like local attribute declarations, but are prefixed by a "define" keyword in the [XPath/XQuery] type system.
[AttributeDecl]definition(targetNCName) |
== |
define [AttributeDecl]content(targetNCName) |
Schema mapping
Local attributes whose type is given by a reference to a global type name are mapped in the type system as follows.
[
|
||||
== | ||||
( attribute targetNCName:NCName { of type QName } )[UseAttribute]use |
References to a global attribute are mapped in the type system as follows.
[
|
|||
== | |||
( attribute QName )[UseAttribute]use |
A local attribute with a local content is mapped to the [XPath/XQuery] type system as follows. Let fs:anonk be a newly generated anonymous name.
[
|
|||||
== | |||||
|
Schema component
The following structure describes attribute declarations in XML Schema.
<element |
[ ignored ] abstract = boolean : false |
[ ignored ] block = (#all | List of (extension | restriction)) |
[ not handled ] default = string |
[ ignored ] final = (#all | List of (extension | restriction)) |
[ not handled ] fixed = string |
[ not handled ] form = (qualified | unqualified) |
[ ignored ] id = ID |
maxOccurs = (nonNegativeInteger | unbounded) : 1 |
minOccurs = nonNegativeInteger : 1 |
name = NCName |
nillable = boolean : false |
ref = QName |
substitutionGroup = QName |
type = QName |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*)) |
</element> |
Schema import distinguishes between global element declarations and local element declarations.
Schema mapping
Global element declarations are mapped like local element declarations, but are prefixed by a "define" keyword in the [XPath/XQuery] type system.
[
|
|||||
== | |||||
define element targetNCName:NCName [substitutionGroupAttribute]substitution [NillableAttribute]nillable of type QName |
[
|
||||||
== | ||||||
define element targetNCName:NCName [substitutionGroupAttribute]substitution [NillableAttribute]nillable [ElementModel]content(targetNCName) |
Schema mapping
Local element declarations, but mapped into corresponding notations in the [XPath/XQuery] type system. Note that substitution group cannot be declared on local elements.
[
|
|||||
== | |||||
( element targetNCName:NCName [NillableAttribute]nillable of type QName ) [OccursAttributes]occurs |
[
|
|||
== | |||
( element QName ) [OccursAttributes]occurs |
Let fs:anonk be a newly generated anonymous name.
[
|
||||||
== | ||||||
|
Schema component
A complex type definition is represented in XML by the following structure.
<complexType |
[ ignored ] abstract = boolean : false |
[ ignored ] block = (#all | List of (extension | restriction)) |
[ ignored ] final = (#all | List of (extension | restriction)) |
[ ignored ] id = ID |
mixed = boolean : false |
name = NCName |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))) |
</complexType> |
Notation
The following auxiliary grammar productions are used to describe the content of a complex type definition.
[57 (Formal)] | ComplexTypeContent |
::= | "annotation"? ("simpleContent" | "complexContent" |
(ChildrenContent AttributeContent)) |
[60 (Formal)] | AttributeContent |
::= | ("attribute" | "attributeGroup")*
"anyAttribute"? |
[58 (Formal)] | ChildrenContent |
::= | ("group" | "all" | "choice" | "sequence")? |
Schema import distinguishes between global complex types (which are mapped to sort declarations) and local complex types (which are mapped to type definitions).
Schema mapping
In the case of global complex types, the mapping rule which applies is denoted by []definition(targetNCName).
[
|
|||||
== | |||||
define type targetNCName:NCName [MixedAttribute ComplexTypeContent]mixed_content(targetNCName) |
Note that the mixed
is passed along in the
normalization rules, in order to map it later on to the appropriate
indication in the [XPath/XQuery] type system.
Schema mapping
In the case of a local complex types, there must not be a name attribute and the mapping rule which applies is denoted by []content(targetNCName).
[
|
||||
== | ||||
[MixedAttribute ComplexTypeContent]mixed_content(targetNCName) |
Note that the mixed
is passed along in the
normalization rules, in order to map it later on to the appropriate
indication in the [XPath/XQuery] type system.
Schema component
A complex type can be of simple content. A simple content is represented in XML by the following structure.
<simpleContent |
[ ignored ] id = ID |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (restriction | extension)) |
</simpleContent> |
Derivation by restriction inside a simple content is represented in XML by the following structure.
<restriction |
base = QName |
[ ignored ] id = ID |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?)) |
</restriction> |
Derivation by extension inside a simple content is represented in XML by the following structure.
<extension |
base = QName |
[ ignored ] id = ID |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?)) |
</extension> |
Notation
The normalization rule
[MixedAttribute ComplexTypeContent]mixed_content(targetNCName) |
== |
TypeDerivation |
maps a pair of mixed attribute and complex type content to a type derivation.
Schema mapping
A complex types with simple content must not have a
mixed
attribute set to "true".
If the simple content is derived by restriction, it is mapped into a simple type restriction in the [XPath/XQuery] type system. Only the name of the base atomic type and attributes are mapped, while the actual simple type restriction is ignored. (Remember that facets are not captured in the [XPath/XQuery] type system.)
[
|
|||||||||
== | |||||||||
restricts QName { [AttributeContent]content(targetNCName) QName } |
If the simple type is derived by extension, it is mapped into an extended type specifier into the [XPath/XQuery] type system.
[
|
|||||||||
== | |||||||||
extends QName { [AttributeContent]content(targetNCName) } |
Schema component
A complex type can be of complex content. A complex content is represented in XML by the following structure.
<complexContent |
[ ignored ] id = ID |
mixed = boolean : false |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (restriction | extension)) |
</complexContent> |
Derivation by restriction inside a complex content is represented in XML by the following structure.
<restriction |
base = QName |
[ ignored ] id = ID |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)) |
</restriction> |
Derivation by extension inside a complex content is represented in XML by the following structure.
<extension |
base = QName |
[ ignored ] id = ID |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))) |
</extension> |
Schema mapping
If the complex content is derived by restriction, it is mapped into a type restriction in the [XPath/XQuery] type system, and the
[
|
|||||||||
== | |||||||||
restricts QName [MixedAttribute]mixed { [AttributeContent]content(targetNCName) [ChildrenContent]content(targetNCName) } |
If the complex content is derived by extension, it is mapped into an extended type specifier into the [XPath/XQuery] type system.
[
|
|||||||||
== | |||||||||
extends QName [MixedAttribute]mixed { [AttributeContent]content(targetNCName) [ChildrenContent]content(targetNCName) } |
Mapping for attribute uses is given in [D.1.4 Special attributes].
Schema component
Model group definitions are represented in XML by the following structure.
<attributeGroup |
[ ignored ] id = ID |
name = NCame |
ref = QName |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?)) |
</attributeGroup> |
Schema mapping
Attribute group definitions are not currently handled by the mapping. See Issue 501 (FS-Issue-0158).
Schema component
Model group definitions are represented in XML by the following structure.
<group |
name = NCame > |
Content: (annotation?, (all | choice | sequence)) |
</group> |
Schema mapping
Model group definitions are not currently handled by the mapping. See Issue 501 (FS-Issue-0158).
Model groups are either "all", "sequence" or "choice". One can also refer to a model group definition.
Schema component
All groups are represented in XML by the following structure.
<all |
[ ignored ] id = ID |
maxOccurs = 1 : 1 |
minOccurs = (0 | 1) : 1 |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, element*) |
</all> |
Schema mapping
All groups are mapped into the "&" operation in the [XPath/XQuery] type system.
[
|
||||
== | ||||
([Element1]content(targetNCName) & ... & [Elementn]content(targetNCName)) [OccursAttributes]occurs |
Schema component
Choice groups are represented in XML by the following structure.
<choice |
[ ignored ] id = ID |
maxOccurs = (nonNegativeInteger | unbounded) : 1 |
minOccurs = nonNegativeInteger : 1 |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (element | group | choice | sequence | any)*) |
</choice> |
Notation
The following auxiliary grammar productions are used to describe group components.
[59 (Formal)] | GroupComponent |
::= | "element" | "group" | "choice" | "sequence" |
"any" |
Schema mapping
Choice groups are mapped into the "|" operation in the [XPath/XQuery] type system.
[
|
||||
== | ||||
([GroupComponent1]content(targetNCName) | ... | [GroupComponentn]content(targetNCName)) [OccursAttributes]occurs |
Schema component
Sequence groups are represented in XML by the following structure.
<sequence |
[ ignored ] id = ID |
maxOccurs = (nonNegativeInteger | unbounded) : 1 |
minOccurs = nonNegativeInteger : 1 |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (element | group | choice | sequence | any)*) |
</sequence> |
Schema mapping
Sequence groups are mapped into the "," operation in the [XPath/XQuery] type system.
[
|
||||
== | ||||
([GroupComponent1]content(targetNCName) , ... , [GroupComponentn]content(targetNCName)) [OccursAttributes]occurs |
Particles contribute to the definition of content models.
A particle can be either an element reference, a group reference or a wildcard.
Schema component
Element reference particles are represented in XML by the following structure.
<element |
ref = QName |
maxOccurs = (nonNegativeInteger | unbounded) : 1 |
minOccurs = nonNegativeInteger : 1 |
[ ignored ] {any attributes with non-schema namespace ...} > |
Schema mapping
Element references are mapped into element references in the [XPath/XQuery] type system.
[
|
|||
== | |||
element QName [OccursAttributes]occurs |
Schema component
Group reference particles are represented in XML by the following structure.
<group |
ref = QName |
maxOccurs = (nonNegativeInteger | unbounded) : 1 |
minOccurs = nonNegativeInteger : 1 |
[ ignored ] {any attributes with non-schema namespace ...} > |
Schema mapping
Model group references are not currently handled by the mapping.
Schema component
Attribute wildcards are represented in XML by the following structure.
<anyAttribute |
[ ignored ] id = ID |
[ not handled ] namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) ) : ##any |
processContents = (lax | skip | strict) : strict |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?) |
</anyAttribute> |
Schema mapping
An attribute wildcard with a "skip" process content is mapped as an attribute wildcard in the [XPath/XQuery] type system.
[
|
||||
== | ||||
(attribute (*,
xs:untypedAtomic ))* |
[
|
||||
== | ||||
attribute * |
[
|
||||
== | ||||
attribute * |
Editorial note | |
Namespace wildcards are not handled by the mapping. |
Schema component
Element wildcards are represented in XML by the following structure.
<any |
[ ignored ] id = ID |
maxOccurs = (nonNegativeInteger | unbounded) : 1 |
minOccurs = nonNegativeInteger : 1 |
[ not handled ] namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) ) : ##any |
processContents = (lax | skip | strict) : strict |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?) |
</any> |
Schema mapping
An element wildcard with a "skip" process content is mapped as an element wildcard in the [XPath/XQuery] type system.
[
|
|||||
== | |||||
( element (*, xs:untyped ) )[OccursAttributes]occurs |
[
|
|||||
== | |||||
( element (*,
xs:anyType ) )[OccursAttributes]occurs |
Editorial note | |
Element wildcards with a "lax" or "strict" process content are not handled by the mapping. |
Editorial note | |
Namespace wildcards are not handled by the mapping. |
All identity-constraints definitions are ignored when mapping into the [XPath/XQuery] type system.
All notation declarations are ignored when mapping into the [XPath/XQuery] type system.
Schema component
A simple type is represented in XML by the following structure.
<simpleType |
[ ignored ] final = (#all | (list | union | restriction)) |
[ ignored ] id = ID |
name = NCName |
[ ignored ] {any attributes with non-schema namespace ...} > |
name = NCName |
</simpleType> |
Derivation by restriction inside a simple type is represented in XML by the following structure.
<restriction |
base = QName |
[ ignored ] id = ID |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?) |
</restriction> |
Derivation by list inside a simple type is represented in XML by the following structure.
<list |
[ ignored ] id = ID |
itemType = QName |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (simpleType?)) |
</list> |
Derivation by union inside a simple type is represented in XML by the following structure.
<union |
[ ignored ] id = ID |
memberTypes = List of QName |
[ ignored ] {any attributes with non-schema namespace ...} > |
Content: (annotation?, (simpleType*)) |
</union> |
Schema import distinguishes between global simple types (which are mapped to sort declarations) and local simple types (which are mapped to type definitions).
Schema mapping
In the case of global simple types, the mapping rule which applies is denoted by []definition(targetNCName).
[
|
||||
== | ||||
define type targetNCName:NCName [SimpleTypeContent]simple_content(targetNCName) |
Schema mapping
In the case of global simple types, the mapping rule which applies is denoted by []content(targetNCName).
[
|
|||
== | |||
[SimpleTypeContent]simple_content(targetNCName) |
Notation
The normalization rule []simple_content(targetNCName) maps a simple type content to a type specifier and an optional occurrence indicator.
Schema mapping
If the simple type is derived by restriction, it is mapped into a simple type restriction in the [XPath/XQuery] type system. The name of the base atomic type and attributes are mapped. Only the minLength, maxLength, and length facets in the simple type restriction are handled. All other properties of the simple-type restriction are ignored.
[
|
||||
== | ||||
restricts QName { QName } [simpleContentRestriction]occurs |
If the simple type is derived by list, and its content type does not constrain the length of the list, it is mapped into a zero-or-more repetition type into the [XPath/XQuery] type system.
[
|
|||
== | |||
{ Type * } |
If the simple type is derived by list, and its content type does constrain the length of the list, then it is mapped into a zero-or-more repetition type into the [XPath/XQuery] type system.
[
|
|||
== | |||
{ Type · OccurrenceIndicator } |
[
|
||
== | ||
{ QName* } |
If the simple type is derived by union, it is mapped into a union type into the [XPath/XQuery] type system.
[
|
|||
== | |||
{ ([SimpleType]content(targetNCName) | ... | [SimpleTypen]content(targetNCName)) } |
[
|
||
== | ||
{ QName1 | ... | QNamen } |
XQuery supports XML Schema validation using the validate expression. This section gives a non-normative formal semantics of XML Schema validation, solely for the purpose of specifying its usage in XQuery.
Specifying XML Schema validation requires a fairly large number of auxiliary judgments. There are two main judgments used to describe the semantics of validation.
The "erase" judgment takes a value and removes all type information from it. This operation is necessary since, in XQuery, validation can occur both on well-formed or already validated documents.
The "annotate" operation takes an untyped value and a type and either fails or succeeds by returning a new -validated- value.
Before defining these two judgments, we first introduce the auxiliary judgments used to describe specific parts of XML Schema's semantics.
Notation
The judgments
and
hold when a type reference (resp. a type derivation) resolves to the given type name and type content.
Semantics
Those judgments are specified by the following rules.
If the type is omitted, it is resolved as the empty sequence type.
statEnv |- OptDerivation OptMixed { empty } resolves to TypeName { Type } |
|
statEnv |- OptDerivation OptMixed { } resolves to TypeName { Type } |
In case of a type reference, then the type name is the name of that type, and the type is taken by resolving the type declaration of the global type.
|
||||
|
||||
statEnv |- of type TypeName resolves to TypeName { Type } |
In the above inference rule, note that BaseTypeName is the base type of the type referred to. So this is indeed the original type name, TypeName, which must be returned, and eventually used to annotated the corresponding element or attribute. However, the type needs to be obtained through a second application of the resolves to judgment.
If the type derivation is a restriction, then the type name is the name of the base type, and the type is taken from the type derivation.
statEnv |- OptMixed Type adjusts to AdjustedType |
|
statEnv |- restricts TypeName OptMixed { Type } resolves to TypeName { AdjustedType } |
If the type derivation is an extension, then the type name is the name of the base type, and the type is the base type extended by the type in the type derivation.
|
|||||
|
|||||
statEnv |- extends TypeName OptMixed { Type } resolves to TypeName { AdjustedType } |
Notation
The judgment
holds if some interleaving of Value1 and Value2 yields Value3. Interleaving is non-deterministic; it is used for processing all groups.
Semantics
This judgment is specified by the following rules.
Interleaving two empty sequences yields the empty sequence.
|
statEnv |- () interleave () yields () |
Otherwise, pick an item from the head of one of the sequences, and recursively interleave the remainder.
Introduction
Finally, we introduce an auxiliary judgment which extracts the value of a given attribute if it exists. This judgment is not used in the semantics of step expressions, but in [8.3 Judgments for type matching], and is based on the other filter judgments.
Notation
The judgment
holds if there are no occurrences of the attribute QName in Value. The judgment
holds if there is one occurrence of the attribute QName in Value, and the value of that attribute is SimpleValue.
Semantics
The filter judgments are defined as follows.
Notation
To define erasure, an auxiliary judgment is needed. The judgment
holds when SimpleValue erases to the string String.
Semantics
This judgment is specified by the following rules.
The empty sequence erases to the empty string.
|
() simply erases to "" |
The concatenation of two non-empty sequences of values erases to the concatenation of their erasures with a separating space.
|
|||||
|
|||||
SimpleValue1,SimpleValue2 simply erases to
fn:concat (String1," ",String2) |
An atomic value erases to its string representation as an
instance of xs:untypedAtomic
.
|
AtomicValueContent of
type AtomicTypeName
simply erases
to dm:string-value (AtomicValueContent) |
Notation
The erases to judgment is used in the definition of the dynamic semantics of validation. The normative dynamic semantics of validation is specified in Section 3.13 Validate ExpressionsXQ. The effect of the validate expression is equivalent to:
serialization of the data model, as described in [XSLT 2.0 and XQuery 1.0 Serialization (Second Edition)], 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 [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)].
Erasure is the formal equivalent of serialization followed by
construction of a new data model value in which all element nodes
are labeled with xs:untyped
and all attribute
nodes with xs:untypedAtomic
.
The judgment
holds when the erasure of Value1 is Value2.
Semantics
This judgment is specified by the following rules.
The empty sequence erases to itself.
|
() erases to () |
The erasure of the concatenation of two values is the concatenation of their erasure, so long as neither of the two original values is simple.
|
|||
|
|||
Value1,Value2 erases to Value1',Value2' |
The erasure of an element is an element that has the same name
and the type xs:untyped
and the erasure of the original content.
|
||
|
||
element ElementName
of type TypeName { Value1 } erases to element ElementName of type xs:untyped { Value2 } |
The erasure of an attribute is an attribute that has the same
name and the type xs:untypedAtomic
and the
simple erasure of the original content labeled with xs:untypedAtomic
.
|
||
|
||
attribute AttributeName of type TypeName { SimpleValue } erases to attribute
AttributeName of type
xs:untypedAtomic {
String of type xs:untypedAtomic } |
The erasure of a document is a document with the erasure of the original content.
The erasure of a text or comment or processing-instruction node is itself.
|
text { String } erases to text { String } |
|
comment { String } erases to comment { String } |
|
processing-instruction NCName { String } erases to processing-instruction NCName { String } |
The erasure of a simple value is the corresponding text node.
|
||
|
||
SimpleValue erases to text { String } |
The annotate as judgment is used in the definition of the dynamic semantics of validation. The normative dynamic semantics of validation is specified in Section 3.13 Validate ExpressionsXQ. The effect of the validate expression is equivalent to:
serialization of the data model, as described in [XSLT 2.0 and XQuery 1.0 Serialization (Second Edition)], followed by
parsing of the serialized value into the Infoset
validation of the Infoset into a Post-Schema Validated Infoset, as described in [Schema Part 1], followed by
construction of a new data model value, as described in [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)].
Annotation is the formal equivalent of schema validation of an
Infoset value into the PSVI followed by construction of a new data
model value. Because the Formal Semantics is defined on data model
values, not the Infoset, annotation is applied to data model values
in which all element nodes are labeled with xs:untyped
and all attribute
nodes with xs:untypedAtomic
-- that
is, the result of erasure.
Notation
The judgment
holds if the result of casting the SimpleValue1 to SimpleType is SimpleValue2.
Semantics
This judgment is specified by the following rules.
Simply annotating a simple value to a union type yields the result of simply annotating the simple value to either the first or second type in the union. Note that simply annotating to the second type is attempted only if simply annotating to the first type fails.
|
||
|
||
statEnv |- simply annotate as SimpleType1|SimpleType2 (SimpleValue1) => SimpleValue2 |
|
|||
|
|||
statEnv |- simply annotate as SimpleType1|SimpleType2 (SimpleValue1) => SimpleValue2 |
The simple annotation rules for ?, +, * are similar.
|
statEnv |- simply annotate as SimpleType? ( () ) => () |
|
||
|
||
statEnv |- simply annotate as SimpleType? (SimpleValue1) => SimpleValue2 |
|
statEnv |- simply annotate as SimpleType* ( () ) => () |
|
|||
|
|||
statEnv |- simply annotate as SimpleType* (SimpleValue1,SimpleValue2) => SimpleValue1',SimpleValue2' |
|
|||
|
|||
statEnv |- simply annotate as SimpleType+ (SimpleValue1,SimpleValue2) => SimpleValue1',SimpleValue2' |
Simply annotating an atomic value to xs:string
yields its string representation.
|
statEnv |- simply annotate as xs:string
(AtomicValue) =>
dm:string-value(AtomicValue) |
Simply annotating an atomic value to xs:decimal
yields the decimal that results from parsing its string
representation.
|
statEnv |- simply annotate as xs:decimal
(AtomicValue) =>
xs:decimal (dm:string-value (AtomicValue)) |
Similar rules are assumed for the rest of the 19 XML Schema primitive types.
Notation
The judgment
holds if it is possible to annotate value Value1 as if it had the nillable type Type and Value2 is the corresponding annotated value.
Semantics
This judgment is specified by the following rules.
If the type is not nillable, then the xsi:nil attribute must not appear in the value, and it must be possible to annotate value Value as if it had the type Type.
|
|||
|
|||
statEnv |- nil-annotate as Type ( Value1 ) => Value2 |
If the type is nillable, and the xsi:nil attribute does not appear or is false, then it must be possible to annotate value Value1 as if it had the type Type.
|
||||
|
||||
statEnv |- nil-annotate as nillable Type ( Value1 ) => Value2 |
If the type is nillable, and the xsi:nil attribute is true, then it must be possible to annotate value Value1 as if it had a type where the attributes in the type are kept and the element content of the type is ignored.
|
|||
|
|||
statEnv |- nil-annotate as nillable (AttributeModel, ElementModel) ( Value1 ) => Value2 |
The annotate as judgment is used in the definition of the dynamic semantics of validation. The normative dynamic semantics of validation is specified in Section 3.13 Validate ExpressionsXQ. The effect of the validate expression is equivalent to:
serialization of the data model, as described in [XSLT 2.0 and XQuery 1.0 Serialization (Second Edition)], followed by
parsing of the serialized value into the Infoset
validation of the Infoset into a Post-Schema Validated Infoset, as described in [Schema Part 1], followed by
construction of a new data model value, as described in [XQuery 1.0 and XPath 2.0 Data Model (Second Edition)].
Erasure is the formal equivalent of serialization followed by
construction of a new data model value in which all element nodes
are labeled with xs:untyped
and all attribute
nodes with xs:untypedAtomic
.
Notation
The judgment
holds if it is possible to annotate value Value1 as if it had type Type and Value2 is the corresponding annotated value.
Note
Assume an XML Infoset instance X1 is validated against an XML Schema S, yielding PSVI instance X2. Then if X1 corresponds to Value1 and S corresponds to Type and X2 corresponds to Value2, the following should hold: annotate as Type ( Value1 ) => Value2.
Semantics
This judgment is specified by the following rules.
Annotating the empty sequence as the empty type yields the empty sequence.
|
statEnv |- annotate as empty (()) => () |
Annotating a concatenation of values as a concatenation of types yields the concatenation of the annotated values.
|
|||
|
|||
statEnv |- annotate as Type1,Type2 (Value1,Value2) => Value1',Value2' |
Annotating a value as a choice type yields the result of annotating the value as either the first or second type in the choice.
statEnv |- annotate as Type1 (Value1) => Value2 |
|
statEnv |- annotate as Type1|Type2 (Value1) => Value2 |
statEnv |- annotate as Type2 (Value1) => Value2 |
|
statEnv |- annotate as Type1|Type2 (Value1) => Value2 |
Annotating a value as an all group uses interleaving to decompose the original value and recompose the annotated value.
Editorial note | |
Jerome and Phil: Note that this may reorder the original sequence. Perhaps we should disallow such reordering. Specifying that formally is not as easy as we would like. |
|
|||||
|
|||||
statEnv |- annotate as Type1 & Type2 ( Value ) => Value' |
The annotation rules for ?, +, * are similar.
statEnv |- annotate as (Type | empty)(Value1) => Value2 |
|
statEnv |- annotate as Type? (Value1) => Value2 |
statEnv |- annotate as Type (Value1) => Value1' statEnv |- annotate as Type* (Value2) => Value2' |
|
statEnv |- annotate as Type+ (Value1,Value2) => (Value1',Value2') |
|
statEnv |- annotate as Type* ( () ) => () |
statEnv |- annotate as Type (Value1) => Value1' statEnv |- annotate as Type* (Value2) => Value2' |
|
statEnv |- annotate as Type* (Value1,Value2) => (Value1',Value2') |
To annotate an element with no xsi:type attribute, first look up the element type, next resolve the resulting type reference, then annotate the value against the resolved type, and finally return a new element with the name of the original element, the resolved type name, and the annotated value.
|
|||||
|
|||||
statEnv |- annotate as ElementType ( element ElementName of type
xs:anyType { Value } ) => element ElementName of type TypeName { Value' } |
To annotate an element with an xsi:type attribute, define a type reference corresponding to the xsi:type. Look up the element type, yielding a type reference, and check that the xsi:type reference derives from this type reference. Resolve the xsi:type reference, then annotate the value against the resolved type, and finally return a new element with the name of the original element, the resolved type name, and the annotated value.
|
|||||||
|
|||||||
statEnv |- annotate as ElementType ( element ElementName of type
xs:anyType { Value } ) => element ElementName of type TypeName { Value' } |
The rule for attributes is similar to the first rule for elements.
|
||||
|
||||
statEnv |- annotate as AttributeType ( attribute
AttributeName of type
xs:anySimpleType { SimpleValue1 } ) => attribute AttributeName of type TypeName { SimpleValue2 } |
Annotating a document node yields a document with the annotation of its contents.
statEnv |- annotate as Type (Value) => Value' |
|
statEnv |- annotate as document { Type } ( document { Value } ) => document { Value' } |
Annotating a text node as text yields itself.
|
statEnv |- annotate as text (text { String }) => text { String } |
Annotating a text nodes as a simple type is identical to casting.
statEnv |- simply annotate as SimpleType ( String ) => SimpleValue' |
|
statEnv |- annotate as SimpleType ( text { String } ) => SimpleValue' |
Annotating a simple value as a simple type is identical to casting.
statEnv |- simply annotate as SimpleType ( SimpleValue ) => SimpleValue' |
|
statEnv |- annotate as SimpleType ( SimpleValue ) => SimpleValue' |
The changes made to this document are described in detail in the Errata to the first edition. The rationale for each erratum is explained in the corresponding Bugzilla database entry. The following table summarizes the errata that have been applied.
Erratum | Bugzilla | Category | Description |
E001 | 1641 3896 | editorial | Make normalization of DirAttributeValue more explicit. |
E002 | 3864 | editorial | Both Core and Formal grammars had symbols 'NamespaceBinding' and 'NamespaceBindings'. To avoid confusion, we rename the Core symbols 'NamespaceBinding[s]' as 'LocalNamespaceDecl[s]', changing all occurrences of the former to the latter. At the same time, we introduce a production for LocalNamespaceDecls (currently assumed). |
E003 | 1647 | editorial | Complete the changes entailed by adding a local-namespaces component to the Core CompElemConstructor. |
E004 | 1746 | editorial | Fix typo in function signature. |
E005 | 1660 | editorial | (superseded) |
E006 | 3875 3184 3885 3194 1715 | editorial | Fix problems involving the domains of statEnv.funcType and dynEnv.funcDefn: Although section 3.1.1 declares the domain of statEnv.funcType to be (expanded-QName, arity), some inference rules neglect the arity. And although section 3.1.2 declares the domain of dynEnv.funcDefn to be expanded-QName(Type1, ..., Typen), this leads to misunderstandings and mistakes; dynEnv.funcDefn should have the same domain as statEnv.funcType. To simplify some of these changes, we introduce the Formal symbol FunctionKey to represent the common domain. |
E007 | 1694 | editorial | Fix miscellaneous small errors in section 5. |
E008 | 1680 | editorial | Fix a bug in the normalization of function calls. |
E009 | 3142 | editorial | Fix some errors in the productions for FunctionSig and TypeList. |
E010 | 3670 | editorial | Clean up due to the removal of op:anyURI-equal from the F+O spec. |
E011 | 3758 3760 | editorial | Correct/simplify/complete the Normalization rules defining []ElementContent and []AttributeContent, and simplify the corresponding Dynamic Evaluation rules. |
E012 | 3771 | editorial | Static Type Analysis must allow for empty text nodes introduced during normalization of direct element constructors. |
E013 | 1754 | editorial | Fix small errors in sections 7.2.1 and 7.2.2. |
E014 | 1756 | editorial | (superseded) |
E015 | 1783 | editorial | Fix some small errors in section 8.4. |
E016 | 3847 | substantive | For internal function fs:idiv, correct the operand types and supporting op: function given in the Binary Operators table. |
E017 | 4371 | editorial | Update the "Processing Model" diagram. |
E018 | 4242 4261 4512 4581 5129 3269 | substantive | Correct various errors in section 8.2.3.1.1. |
E019 | 4578 | substantive | Correct a normalization error in section 4.3.2 Filter Expressions. |
E020 | 4766 | editorial | Correct errors in examples in section 2.4.4. |
E021 | 3818 | substantive | Avoid loss of type information in normalized path expressions. |
E022 | 3946 | substantive | Make the static typing of processing-instructions consistent with their dynamic typing. |
E023 | 3269 | editorial | ElementNameOrWildcard and AttributeNameOrWildcard do not derive empty. |
E024 | 4841 | editorial | Introduce fs:item-at() function. |
E025 | 5601 | substantive | For internal function fs:div, correct the result type in the Binary Operators table. |
E026 | 1757 | editorial | Fix small errors in section 7.2.4 [The fn:boolean function]. |
E027 | 5651 | substantive | Provide (non-default) static typing for fn:not(). |
E028 | 5670 | substantive | Call fn:boolean() in normalization of Where clause |
E029 | 3655 3771 4869 | substantive | Don't use the "interleave with empty text nodes" technique for element constructors. |
E030 | 5986 | editorial | Fix cross-reference in 4.7.3.4. |
E031 | 3771 | substantive | Don't use the "interleave with empty text nodes" technique for attribute constructors. |
E032 | 5747 | substantive | Rework the rules for CastableExpr to avoid raising type errors (and fix various other problems). |
E033 | 5459 5460 | substantive | Fix the static typing for numeric and aggregate functions. |
E034 | 1776 | editorial | Adjust the formatting of a rule in 8.2.2.2 [Dynamic semantics of axes]. |
E035 | 3193 | editorial | Fix typo in 5.14 [Variable Declaration]. |
E036 | 3268 | editorial | Introduce Formal symbol OptDerivation. |
E037 | 3861 | editorial | Fix typo in 2.1.4 [Notations for inference rules]. |
E038 | 3864 | editorial | Fix typos in 2.3.1 [Formal values]. |
E039 | 3865 | editorial | Fix typo in 2.3.2 [Examples of values]. |
E040 | 3866 | editorial | Fix typos in 2.4.1 [XML Schema and the [XPath/XQuery] Type System]. |
E041 | 3868 | editorial | Fix typos in 2.4.3 [Content models]. |
E042 | 3871 | editorial | In the production for Definitions, add a semicolon after each Definition. Adjust the rest of the spec accordingly. |
E043 | 3871 | editorial | Fix typos in 2.4.4 [Top level definitions]. |
E044 | 3873 | editorial | Fix typo in 2.5 [Functions and operators]. |
E045 | 3876 | editorial | Fix typo in 3.2.2 [Normalization mapping rules]. |
E046 | 3879 | editorial | Fix typos in 4 [Expressions]. |
E047 | 3882 | editorial | Change some wording in 4.1.5 [Function Calls] / Normalization. |
E048 | 3883 | editorial | Change some wording in 4.1.5 [Function Calls] / Static Type Analysis. |
E049 | 3885 | editorial | Minor changes in 4.1.5 [Function Calls] / Dynamic Evaluation. |
E050 | 3886 | editorial | Fix typo in 4.2.1 [Steps]. |
E051 | 6005 | markup | Correctly render metavariables in mapping subscripts. |
E052 | 3895 | editorial | Change some wording in 4.7.1 [Direct Element Constructors]. |
E053 | 4447 | editorial | Fix incorrect references to standard functions/operators. |
E054 | 4593 | editorial | Fix typo in 8.4 [Judgments for FLWOR and other expressions on sequences]. |
E055 | 4601 | editorial | Change wording re fs:convert-operand in 4.5.2 [General Comparisons]. |
E056 | 6007 | markup | Fix italicization in C.2 [Mapping of Overloaded Internal Functions]. |
E057 | 6160 | substantive | Fix the static typing for fs:convert-operand(). |
E058 | 5254 | substantive | Fix the static typing for ValidateExpr. |
E059 | 4189 | substantive | Fix various bugs in the 'union interpretation' rules. |
E060 | 6538 | substantive | Fix behaviour of following-sibling axis re attribute nodes. |
E061 | 4273 | substantive | Fix unsoundness of 'data on' judgment. |
E062 | 5452 | substantive | Don't define the static type of the namespace axis. |