diff --git a/specifications/xquery-40/src/expressions.xml b/specifications/xquery-40/src/expressions.xml index 2451a8fe1..f6c316d52 100644 --- a/specifications/xquery-40/src/expressions.xml +++ b/specifications/xquery-40/src/expressions.xml @@ -5681,8 +5681,10 @@ name.

The equivalent in XSLT is:

- ]]> + + + +]]> diff --git a/specifications/xslt-40/src/element-catalog.xml b/specifications/xslt-40/src/element-catalog.xml index fdaa0f0ed..db0904f4c 100644 --- a/specifications/xslt-40/src/element-catalog.xml +++ b/specifications/xslt-40/src/element-catalog.xml @@ -95,6 +95,7 @@ + @@ -121,6 +122,7 @@ + @@ -840,12 +842,12 @@ - + - + - + @@ -854,6 +856,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -897,9 +940,6 @@ - - - diff --git a/specifications/xslt-40/src/schema-for-xslt40.xsd b/specifications/xslt-40/src/schema-for-xslt40.xsd index 9c2836504..359200ec4 100644 --- a/specifications/xslt-40/src/schema-for-xslt40.xsd +++ b/specifications/xslt-40/src/schema-for-xslt40.xsd @@ -972,7 +972,6 @@ of problems processing the schema using various tools - @@ -981,7 +980,6 @@ of problems processing the schema using various tools - diff --git a/specifications/xslt-40/src/xslt.xml b/specifications/xslt-40/src/xslt.xml index 6dae9151f..a9e5076ea 100644 --- a/specifications/xslt-40/src/xslt.xml +++ b/specifications/xslt-40/src/xslt.xml @@ -4033,10 +4033,9 @@

The xsl:function, xsl:template, xsl:attribute-set, xsl:variable, - and - xsl:mode + xsl:mode, xsl:item-type, and xsl:record-type declarations each have an optional - visibility attribute. The value is one of private, + visibility attribute. The permitted value is some subset of private, public, abstract, or final (never hidden). In the case of an xsl:param element there is no explicit @@ -4075,7 +4074,7 @@

The visibility of a named template, function, variable, attribute set, mode, - or named item type + named item type, or named record type declared within a package is the first of the following that applies, subject to consistency constraints which are defined below:

@@ -4836,18 +4835,29 @@ -

Except where recursive types are involved, a named item type +

A named item type (declared in an xsl:item-type declaration) is considered - identical to its expansion. With recursive types, the same type names must - be used. By implication, the named type must itself be declared or exposed - with visibility="final".

+ identical to its expansion.

+
+ + +

Two named record types are compared by name, not by content. This is + because named record types may potentially be recursive, so the name + cannot always be expanded to an expressible record type designator. + By implication, the named record type must itself be declared or exposed + with visibility="public".

-

Modes are not overridable, so the xsl:mode declaration cannot - appear as a child of xsl:override.

+

Modes, named item types, and named record type are not overridable, + so xsl:mode, xsl:item-type, and + xsl:record-type declarations cannot + appear as children of xsl:override. However, + the constructor function implicitly created from an + xsl:record-type declaration may be overridden + in an xsl:function declaration.

Referring to Overridden Components @@ -6548,6 +6558,9 @@ and version="1.0" otherwise.

xsl:preserve-space + + xsl:record-type + xsl:strip-space @@ -10547,11 +10560,13 @@ and version="1.0" otherwise.

contains entries with keys "first" and "last".

-

type(complex) matches any value that is an instance of the item type declared in an xsl:item-type +

type(complex) matches any value that is an instance of the item type + declared in an xsl:item-type or xsl:record-type declaration with name "complex"

-

type(complex)[?i eq 0] matches any value that is an instance of the item type declared in an xsl:item-type +

type(complex)[?i eq 0] matches any value that is an instance of the + item type declared in an xsl:item-type or xsl:record-type declaration with name "complex" and that is a map with an entry having key i and value zero.

@@ -11119,76 +11134,458 @@ and version="1.0" otherwise.

- - Defining Named Item Types + + Named Types - - - Named item types can be declared using the new xsl:item-type - element. This is designed to avoid repeating lengthy type definitions (for example - function types and record types) every time they are used. [This feature was - present in the editor's draft presented to the WG when it started work.] - - +

XSLT 4.0 introduces two new and closely-related constructs allowing item + types to be given names, and to be referred to by name anywhere that item types + are used, for example in function declarations and variable declarations.

- +

The xsl:item-type declaration allows any item type to be given + a name. It is particularly useful to avoid repetitive use of the same choice types, + enumeration types, or function types, and means that if the definition changes, the change only + needs to be made in one place.

-

An xsl:item-type declaration associates a name with an item type, and allows the type - to be referenced by name throughout the stylesheet package.

- -

The following example declares a named item type for complex numbers, and uses it in a variable - declaration and a function declaration.

- - +

The xsl:record-type declaration takes this a step further. + Like xsl:item-type, it allows a name to be given to any + record type. In addition, though, it offers two further capabilities:

+ + +

Named record types can be recursive, allowing definitions of + recursive data structures such as lists and trees.

+

Declaring a named record type automatically establishes + a constructor function for records of that type; the constructor + function has the same name as the record type itself.

+
+ + + Named Item Types + + + + + Named item types can be declared using the new xsl:item-type + element. This is designed to avoid repeating lengthy type definitions (for example + function types) every time they are used. [This feature was + present in the editor's draft presented to the WG when it started work.] + + + + + +

An xsl:item-type declaration associates a name with an item type, and allows the type + to be referenced by name throughout the stylesheet package.

+ +

The following example declares a named item type for colors, and uses it in three variable + declarations and a function declaration.

+ + + + + + + + + + #FF0000 + #008000 + #0000FF + + + ]]> + +
+ + +

The following example declares a named choice type for the two binary + types xs:hexBinary and xs:base64Binary + and uses it in a function declaration that compares two such values + for equality.

+ + + + + + + + ]]> + +
+ +

Using named item types makes the stylesheet more readable, and improves potential for change: a change + to the set of colors allowed by the type my:color is less likely to affect users of a function + library. However, named item types do not provide true encapsulation or information hiding; users of the + function library can still treat enumeration values as simple strings if they wish.

+

The xsl:item-type declaration adds an entry to the + + component of the static context for XPath expressions, and also becomes available for use wherever + XSLT allows an ItemType to appear.

+

The scope of a named item type is the in which it is declared. If it + is declared with visibility="public" then it also becomes available for use in using + packages. (Since there is no mechanism for the using package to override the definition, + public effectively means final.)

+

A named item type is essentially an abbreviation for the item type designator appearing in the + as attribute, and the semantics can be defined in terms of textual replacement + of the name by its definition. In consequence, named item types cannot be recursive, since + this would make the textual expansion non-terminating.

+

The name of the item type is the expanded name formed by resolving the name attribute. + A lexical QName with no prefix is treated as being in the + .

+

If two xsl:item-type declarations in a have the same + name, then the one with higher is used.

+

+

It is a static error if a package contains two + xsl:item-type or xsl:record-type + declarations having the same name and the same import + precedence, unless there is another definition with the same + name and higher import precedence. It is also a static error if the name + of the item type uses a , or if it has the same + name as a type in the in-scope schema types of + the static context.

+

+ +

+

It is a static error for an item type named + N to contain in its as attribute a reference to N, + or to an item type that references N directly or indirectly.

+

+

It is permissible to use a private named item type in the declaration of a public + variable, function, or template. A package that uses (or overrides) such a component + will not be able to use the type name, but it can use the underlying type definition, + or provide its own declaration of the relevant item type, using the same name or + a different name.

+
+ + Named Record Types + + + Named record types are introduced. + + + + + + +

An xsl:record-type declaration associates a name + with a record type, and allows the record type + to be referenced by name throughout the stylesheet package.

+ + +

The following example declares a named record type for complex numbers, + and uses it in a variable + declaration and a function declaration.

+ + + + + - + - ]]> -

Note how the item type declaration has implicitly declared a constructor function - cx:complex that can be used to create instances of the item type; - details of this mechanism are at .

-
-

Using named item types makes the stylesheet more readable, and improves potential for change: a change - to the way complex numbers are implemented in this example is less likely to affect users of the function - library. However, named item types do not provide true encapsulation or information hiding; users of the - function library can still treat complex numbers as raw maps if they wish.

-

The xsl:item-type declaration adds an entry to the - - component of the static context for XPath expressions, and also becomes available for use wherever - XSLT allows an ItemType to appear.

-

The scope of a named item type is the in which it is declared. If it - is declared with visibility="final" then it also becomes available for use in using - packages. Named item types cannot be overridden in a using package, so the only permitted values for - visibility are private and final.

-

The name of the item type is the expanded name formed by resolving the name attribute. - A lexical QName with no prefix is treated as a no-namespace name.

-

If two xsl:item-type declarations in a have the same - name, then the one with higher is used.

-

-

It is a static error if a package contains two - xsl:item-type - declarations having the same import - precedence, unless there is another definition of the same - item type with higher import precedence.

-

-

An item type declaration may refer directly or indirectly to itself if - it satisfies the conditions defined in . - This allows types to be declared that match recursive data structures such as linked lists - and trees.

-

-

It is a static error for an item type named - N to contain in its as attribute a reference to N, - or to an item type that references N directly or indirectly, unless it satisfies - the conditions defined in .

-

-

TODO: add named item types to xsl:accept and xsl:expose. Clarify that when a function or variable - is exported to a different package, its declared type/signature uses the expanded form of any named - item type; there is no requirement for the using package to know the named item types. But it becomes - easier to use the exposed variables and functions if the names of the types are exposed too.

+]]>
+

Note how the record type declaration has implicitly declared a constructor function + cx:complex that can be used to create instances of the item type.

+
+ +

+

It is a + if the names of the fields in an xsl:record-type + declaration are not distinct.

+

+ +

+

It is a + if an xsl:field element has a default + attribute unless it specifies required="no".

+

+ +

An xsl:record-type declaration has two effects:

+ + +

In the same way as xsl:item-type, it defines + a named item type in the static context, allowing the record type to + be referenced by name anywhere an ItemType can appear, + for example in the declarations of functions and variables. Unlike + types declared in xsl:item-type, however, + named record types can be recursive.

+

An xsl:record-type declaration also + implicitly defines a constructor function, of the same name, + and adds this to the set of + + in the static context.

+
+ +

Because of its dual role, the name of an xsl:record-type + declaration must be valid both as an item type name and as a function name. + This means the name must be distinct from other type names and function names + in the static context. It also means that the name must be in a namespace.

+ +

Considered as an item type, the xsl:record-type + declaration is equivalent to an xsl:item-type declaration + formed by the following template rule, evaluated in the context of + a namespace alias <xsl:namespace-alias stylesheet-prefix="t" + result-prefix="xsl"/>:

+ + + + + record( + + + {@name}{'?'[$optional]} as {@as otherwise 'item()*'} + + + , * + + ) + + + +]]> +

This generated xsl:item-type declaration must + meet all the constraints placed on user-written + xsl:item-type declarations, including the rule + requiring names to be unique, but not including the rule + disallowing recursive references.

+ +

For example, the declaration:

+ + + + +]]> + +

produces the equivalent item type declaration:

+ + ]]> + +

Considered as a function declaration, an xsl:record-type + declaration is equivalent to an xsl:function declaration + formed by the following template rule, evaluated in the context of + a namespace alias <xsl:namespace-alias stylesheet-prefix="t" + result-prefix="xsl"/>:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + +

For example, the declaration:

+ + + + +]]> + +

produces the equivalent function declaration:

+ + + + + + + + +]]> + +

No entry is generated in the constructed map for a field that + is declared as optional with no default. So the declaration:

+ + + + +]]> + +

produces the equivalent function declaration:

+ + + + + + + + + + +]]> + +

If the record type is extensible, the generated function + includes an optional options parameter So the declaration:

+ + + + +]]> + +

produces the equivalent function declaration:

+ + + + + + + + + + +]]> + +

This generated xsl:function declaration must + meet all the constraints placed on user-written + xsl:function declarations, including the rule + requiring the combination of name and arity to be unique.

+ +

The generated xsl:function declaration has the + import precedence associated with the stylesheet module in which the + xsl:record-type declaration appears, and it may be + overridden by another xsl:function declaration with + higher import precedence. If the visibility is public + then it can also be overridden using xsl:override + in another .

+ +

The scope of a named record type is the in which it is declared. If it + is declared with visibility="public" then it also becomes available for use in using + packages.

+

The name of the record type is the expanded name formed by resolving the name attribute. + Because function names are always in a namespace, the name must be prefixed.

+ +

If two xsl:record-type declarations in a have the same + name, then the one with higher is used.

+

+

It is a static error if a package contains two + xsl:record-type + declarations having the same import + precedence, unless there is another definition of the same + record type with higher import precedence.

+

+

A record type declaration may refer directly or indirectly to itself if + it satisfies the conditions defined in . + This allows types to be declared that match recursive data structures such as linked lists + and trees.

+

+

It is a static error for an item type named + N to contain in its as attribute a reference to N, + or to an item type that references N directly or indirectly, unless it satisfies + the conditions defined in .

+

+ +

A named record type with visibility private may be used in the definition of a + component (such as a variable, a function, a template, or another named record + type) that is itself public. Another package may reference such a component + even though it cannot reference the types used in its definition. The fact that the + record type is private, however, means that it is impossible to + override a variable or function that references the record type.

+ + + Defining a Binary Tree +

This example illustrates the definition of a recursive record type. + The record type represents a node of a binary tree containing a payload value + in each node, together with optional references to left and right subtrees. + As well as the data fields, the record type defines a depth function + that returns the maximum depth of the tree, by making recursive calls on its + subtrees.

+ + + + + + +]]> + +

The =?> operator is described in + . Its effect + is to make a dynamic call on a function item that is present as + an entry in a map, passing that map implicitly as the first argument. + It thus mimics method invocation in object-oriented languages, though + there is no inheritance or encapsulation.

+ +

The following code builds a simple tree and calculates its depth:

+ + depth()]]> + + +

Returning the result 3.

+
+
Defining a Decimal Format @@ -12690,11 +13087,16 @@ and version="1.0" otherwise.

} ]

The following template rules are used. The setting expand-text="yes" is assumed:

- + + + + + + +

Christmas Book Selection

@@ -12711,6 +13113,7 @@ and version="1.0" otherwise.

+ {?Title} @@ -12718,7 +13121,7 @@ and version="1.0" otherwise.

{?Category} ${?Price} -
+ ]]>