| ComparisonExpr [18] | A = B, A eq B, A is
B |
xs:boolean |
| StringConcatExpr [19] | A || B |
xs:string |
| RangeExpr [20] | A to B |
xs:integer |
| AdditiveExpr [21] | A + B |
xs:anyAtomicType |
| MultiplicativeExpr [22] | A * B |
xs:anyAtomicType |
| UnionExpr [23] | A | B |
the least common supertype of A and B |
| IntersectExceptExpr [24] | A intersect B, A except
B |
the type of A |
| InstanceOfExpr [25] | A instance of T |
xs:boolean |
| TreatExpr [26] | A treat as T |
the item type of T |
| CastableExpr [27] | A castable as T |
xs:boolean |
| CastExpr [28] | A cast as T |
the type T |
| UnaryExpr [29] | -N |
numeric |
| SimpleMapExpr [34] | A ! B |
the type of B |
| PathExpr [35] | / |
document-node() |
/P |
the type of P | |
//P |
the type of P | |
| RelativePathExpr [36] | A/B, A//B |
the type of B |
| AxisStep [36] | A[P] |
the type of A |
| ForwardStep [39] , ReverseStep [42] | Axis::NodeTest |
If the NodeTest is a
KindTest K, then K (for example,
element() or comment() ). Otherwise (the
NodeTest is a NameTest ), the type
corresponding to the principal node kind of the axis, for example
element() or attribute() . |
| PostfixExpr [48] | Filter Expression
A[B] |
the type of A |
Dynamic Function Call A(B,
C) |
the return type of the function type of A | |
| Literal [53] | "pH" ,
93.7 |
xs:string ,
xs:integer , xs:decimal , or
xs:double , depending on the form of the literal |
| VarRef [55] | $V | For a variable declared using
xsl:variable or
xsl:param , and for
parameters of inline function expressions: the declared type of the
variable, defaulting to item() . For variables declared
using for, let, some, and every expressions: the item type of the
expression to which the variable is bound. For the binding
variables of xsl:for-each-group: the type of the relevant
expression in the xsl:for-each-group
instruction (select , group-by , or
group-adjacent ) |
| ParenthesizedExpr [57] | (E) |
the type of E |
() |
xs:error (a type that
has no instances) |
|
| ContextItemExpr [58] | . |
the context item type: see below |
| FunctionCall [59] | F(X, Y) |
the declared result type of function F |
| NamedFunctionRef [63] | F#n |
the declared function type of the referenced function F |
| InlineFunctionExpr [64] | function(P) {E} |
the declared type of the anonymous inline function |
| MapExpr [202] | map{"A":E, "B":F} |
map(*) |
In some cases the above entries require computation of the least common type of two types T and U. Since item types form a lattice rather than a hierarchy, there may be a set of types V such that T and U are both subtypes of every type in V, and no type in V is unambiguously the "least" common type in the sense that all the others are subtypes of it. In this situation the choice of which type in V to use as the inferred static type is implementation-defined.
Note:
The streamability analysis in this chapter is not schema-aware. There are cases where use of schema type information might enable a processor to determine that a construct is streamable when it would be unable to make this determination otherwise. Two examples:
A processor might decide that a construct such as price +
salesTax
is streamable if both the child elements have a
simple type such as xs:decimal
, or if the order in
which they appear in the input document is known.
A processor might decide that a step using the descendant axis,
such as .//title
, has striding rather than crawling
posture
if it can establish that two title
elements will never
overlap (that is, a title
cannot contain another
title
). This would allow the instruction
<xsl:apply-templates select=".//title"/>
to be
used in a streaming template rule.
Although such constructs are not guaranteed streamable according to this specification, there is nothing to prevent a processor providing a streamed implementation if it is able to do so.
[Definition: For every expression, it is possible to establish by static analysis, information about the item type of the context item for evaluation of that expression. This is called the context item type of the expression.]
The semantics of every construct, defined in this specification
or in the XPath specification, describe how the focus for
evaluating each operand of the construct is determined. In most
cases the focus is the same as that of the parent construct. In
some cases the focus is determined by evaluating some other
expression, for example in the expressions A/B
,
A!B
, or A[B]
, the focus for evaluating
B is A. More generally:
[Definition: A focus-changing construct is a construct that has one or more operands that are evaluated with a different focus from the parent construct.]
Note:
Examples of focus-changing constructs include the instructions
xsl:for-each
, xsl:iterate
, and xsl:for-each-group
; path
expressions, filter expressions, and simple mapping expressions;
and all patterns.
[Definition: Within a focus-changing construct there is in many cases one operand whose value determines the focus for evaluating other operands; this is referred to as the controlling operand.]
Note:
For example, the controlling operand of a xsl:for-each
, xsl:iterate
, or xsl:for-each-group
instruction is the expression in its select
attribute;
the controlling operand of a filter expression E[P]
is
E
, and the controlling operand of a simple mapping
expression A!B
is A
.
[Definition: Within a focus-changing construct there
are one or more operands that are evaluated with a focus determined by
the controlling operand (or in some
cases such as xsl:on-completion
, with
an absent
focus); these are referred to as
controlled operands.]
Note:
For example, the main controlled operand of a xsl:for-each
, xsl:iterate
, or xsl:for-each-group
instruction is the contained sequence constructor; the controlled
operand of a filter expression E[P]
is P
,
and the controlled operand of a simple mapping expression
A!B
is B
.
[Definition: The focus-setting container of
a construct C is the innermost focus-changing construct
F (if one exists) such that C is directly or
indirectly contained in a controlled operand of
F. If there is no such construct F,
then the focus-setting container is the containing declaration, for example an xsl:function
or xsl:template
element.]
Note:
For example, if an instruction appears as a child of xsl:for-each
, then its
focus-setting container is the xsl:for-each
instruction; if
an expression appears within the predicate of a filter expression,
its focus-setting container is the filter expression.
The context item type of a construct C is the first of the following that applies:
If the focus-setting container of
C is an xsl:function
element, an
inline function declaration, or an xsl:on-completion
element, then the context item type is xs:error
.
Note:
This is essentially an error case; expressions that depend on the focus should not normally appear within a construct that sets the focus to absent.
If the focus-setting container of
C is an xsl:stream
instruction, then the
context item type is document-node()
.
If the focus-setting container of C is a template rule, then the context item type is the match type of the match pattern of the template rule, defined below.
If the focus-setting container of
C is a PredicatePattern
, then the context
item type is item()
.
If the focus-setting container is any
other declaration, for example a global variable
declaration, the context item type is item()
.
Otherwise, the context item type is the statically-inferred type (see 19.2 Determining the Static Type of a Construct) of the controlling operand of the focus-setting container of C.
[Definition: The
match type of a pattern is the most specific
ItemType
that is known to match all items that the
pattern can match.] The match type
of a pattern is the statically-inferred item type of the pattern's
equivalent expression, determined according to the rules in
19.2 Determining the Static
Type of a Construct. For example, the match type of the
pattern para[1]
is element()
, while that
of the pattern @code[.='x']
is
attribute()
An operand role gives information about the operands of a particular kind of construct. The two important properties of an operand role are the required type and the operand usage.
The usage of an operand role is relevant only when the value of an operand supplied in that role is a node, or a sequence that contains nodes. It is one of the following:
[Definition: An
operand usage of absorption indicates that the construct
reads the subtree(s) rooted at a supplied node(s).] Examples are constructs that atomize their
operands, or that obtain the string value of a supplied node, or
that copy the supplied node to a new tree. Another example is the
deep-equal
FO30
function, which compares the subtrees rooted at the nodes supplied
in its first two arguments.
[Definition: An
operand usage of inspection indicates that the construct
accesses properties of a supplied node that are available without
reading its subtree.] Examples are
functions such as name
FO30
and base-uri
FO30,
and the instance of
expression which tests the type of
a node (or other item). or functions such as count
FO30,
exists
FO30,
and boolean
FO30
which are only interested in the existence of the node, and not in
its properties.
[Definition: An operand usage of transmission indicates that the construct will (potentially) return a supplied node as part of its result to the calling construct (that is, to its parent in the construct tree).] It also indicates that document order is preserved: if the input is in document order, then the result must be in document order. An example is a filter expression, where nodes in the base expression (the expression being filtered) will typically appear in the result of the filter expression, in their original order.
[Definition: An
operand usage of navigation indicates that the construct may
navigate freely from the supplied node to other nodes in the same
tree, in a way that is not constrained by the streamability
rules.] This covers several cases:
cases where it is known that the construct performs impermissible
navigation (for example, the xsl:number
instruction) or
reordering (the reverse
FO30
function), or that require look-ahead (the innermost
FO30
function) and also cases where the analysis is unable to determine
what use is made of the node, for example because it is passed as
an argument to a user-defined function, or retained in a
variable.
The assignment of operand usages to each operand role of each kind of construct is defined in 19.8 Classifying Constructs.
Consider the following construct:
<xsl:stream href="emps.xml"> <xsl:for-each select="*/emp"> <xsl:value-of select="."/> </xsl:for-each> </xsl:stream>
To assess the streamability, we follow the following logic:
The top-level construct is a sequence constructor. It is evaluated with a document node as the context item, and with a striding posture.
The sequence constructor has one child instruction, which has an operand usage of transmission.
The xsl:for-each
instrunction evaluates its select
expression, with the
context item and posture unchanged.
The step child::*
is evaluated with this context
item and posture. The posture transition rules permit this; we now
have a sequence of child elements, and still a striding posture.
The same applies to the next step, child::emp
The content of the xsl:for-each
instruction is a
sequence constructor which itself
has a single operand, the xsl:value-of
instruction.
The xsl:value-of
instruction is evaluated once for each emp
child, with
that child as context item and in a striding posture. This
instruction uses the general
streamability rules. The operand usage of the
select
expression is absorption. This means that the
result of the xsl:value-of
instruction is
grounded and consuming.
The result of the trivial sequence constructor contained in the
xsl:for-each
instruction is therefore grounded and consuming
The result of the xsl:for-each
instruction (see
<IP_ADDRESS> Streamability of
xsl:for-each) is therefore grounded and consuming
The result of the trivial sequence constructor contained in the
xsl:stream
instruction
is therefore grounded and consuming
The xsl:stream
instruction is therefore guaranteed-streamable.
Now consider a slightly different construct:
<xsl:stream href="emps.xml"> <xsl:for-each select="*/emp"> <xsl:sequence select="."/> </xsl:for-each> </xsl:stream>
To assess the streamability, we follow the following logic:
The top-level construct is a sequence constructor. It is evaluated with a document node as the context item, and with a striding posture.
The sequence constructor has one child instruction, which has an operand usage of transmission.
The xsl:for-each
instruction evaluates its select
expression, with the
context item and posture unchanged.
The step child::*
is evaluated with this context
item and posture. The posture transition rules permit this; we now
have a sequence of child elements, and still a striding posture.
The same applies to the next step, child::emp
The content of the xsl:for-each
instruction is a
sequence constructor which itself
has a single operand, the xsl:sequence
instruction.
The xsl:sequence
instruction is evaluated once for each emp
child, with
that child as context item and in a striding posture. This
instruction uses the general
streamability rules. The operand usage of the
select
expression is transmission. This means that
the result of the xsl:sequence
instruction is
striding and motionless.
The result of the trivial sequence constructor contained in the
xsl:for-each
instruction is therefore also striding and motionless.
The result of the xsl:for-each
instruction (see
<IP_ADDRESS> Streamability of
xsl:for-each) is therefore striding and motionless.
The result of the trivial sequence constructor contained in the
xsl:stream
instruction
is therefore striding and motionless.
The xsl:stream
instruction is therefore not guaranteed-streamable.
Expressed informally, the result of an xsl:stream
instruction (or of a
streamable template rule) must not contain streamed nodes. The
reason for this is that once streamed nodes are returned to
constructs that are not declared streamable and therefore have no
streamability constraints, there is no way to analyze what happens
to them, and thus to guarantee streamability.
Consider the expression .//chapter
.
When this appears as an argument to the function count
FO30
or exists
FO30,
it can be streamed (it is a consuming expression, meaning that the
subtree rooted at the context item needs to be read in order to
evaluate the expression). A possible strategy for performing a
streamed evaluation is to read all descendants of the context item
in document order, checking each one to see whether its name is
chapter
. The sweep of the expression will be consuming, and
its posture will be crawling.
The operand usage (the usage of the argument to
count
FO30
or exists
FO30)
is defined as a inspection. The general streamability rules
show that when the posture of an operand is crawling and the operand
usage is inspection, the resulting expression is
motionless
When the same expression appears as an argument to a call on a
user-defined function, and the declared type of the relevant
argument is node()*
, then it is not possible to
determine whether the expression is streamable or not, because the
streamability analysis does not attempt to follow the data flow
across functions (also, the function in question could be
overridden in another package). This operand usage (where
an expression returns nodes and the processor cannot determine how
those nodes might be used) is defined as navigation. The
expression in this context is classified as roaming and free-ranging, which effectively means that
streaming is not guaranteed. Although the expression is not
guaranteed streamable, some processors might do better, for example
by examining what the called function does with the argument, or by
allowing the stylesheet author to make assertions about the
behavior of the called function using extension attributes.
When the same expression appears as an argument to the function
string-join
FO30,
the processor knows that it will need to access the subtree of each
selected section
element in order to compute the
result of the function (the argument to string-join
FO30
is classified as having operand usage absorption). The
processor does not know, however, whether these subtrees will be
overlapping (one section
might contain another). If
they are overlapping, the expression will not be streamable. The
analysis assumes the worst case, so it classifies the expression as
free-ranging, which effectively means that
streaming is not guaranteed. Some processors might do better, for
example by using schema-based inferencing.
The posture of an construct indicates the relationship of the nodes selected by the construct to a streamed input document. The value is one of the following:
[Definition: Grounded: indicates that the value returned
by the construct does not contain nodes from the streamed input
document]. Atomic values and
function items are always grounded; nodes are grounded if it is
known that the they are in a non-streamed document. For example the
expressions doc('x')
and copy-of(.)
both
return grounded nodes.
[Definition: Climbing: indicates that nodes returned by
the construct are reached by navigating the parent,
ancestor[-or-self], attribute, and/or namespace axes from the node
at the current streaming position.]
When the context posture is climbing, use
of certain axes such as parent
and
ancestor
is permitted, but use of other axes such as
child
or descendant
violates the
streamability rules.
[Definition: Crawling: typically indicates that nodes
returned by a construct are reached by navigating the
descendant[-or-self] axis.] Nodes
reached in this way potentially have overlapping subtrees, so
further downward navigation is not permitted. Expressions
that can be statically determined to return a singleton node (for
example head(.//title)
) generate a result with no
overlapping subtrees, so they are striding rather than
crawling.
[Definition: Striding: indicates that the result of a
construct is a sequence of nodes, in document order, that are peers
in the sense that none of them is an ancestor or descendant of any
other.] This is typically achieved
by using one or more steps involving the child axis only. Use of
the outermost
FO30
function can also result in a striding posture, as can
functions such as head
FO30
or zero-or-one
FO30
that ensure the result will be a singleton node.
[Definition: Roaming:
indicates that the nodes returned by an expression could be
anywhere in the tree, which inevitably means that the construct
cannot be evaluated using streaming.] For example, the posture of an axis step using the
following
or preceding
axis will
typically be roaming, which leads the analysis to conclude
that the construct is not streamable.
Note:
One way to think about the posture values is as labels for
states in a finite state automaton, where the alphabet of symbols
accepted by the automaton is the set of 13 XPath axes, and the
sentence being parsed is a path expression containing a sequence of
axis steps. For example, use of the descendant
axis
when the current state is striding moves the new state to
crawling, and use of the parent
axis then takes
it to climbing.
The posture of a construct is determined in one of several ways:
For axis steps, the posture of the expression is determined by the context posture and the choice of axis. For example, an axis step using the ancestor axis always has a posture of climbing, while an axis step using the child axis, if the context posture is striding, will itself have a posture of striding. The rules for the posture transitions produced by axis steps are given in <IP_ADDRESS> Streamability of Axis Steps.
For many other constructs, the posture is determined by the general streamability rules. These determine the result posture in terms of the operands to the construct and the way in which each operand is used. For example, a construct that accepts a streamed node as the value of an operand, and atomizes that node, will generally have a posture of grounded.
Other constructs have their own special rules, which are all
listed in this chapter. For example, a call on the root
FO30
function behaves analogously to an axis step, and is described in
<IP_ADDRESS> Streamability of the
root function. Special rules are needed for:
Constructs that evaluate an operand more than once, such as an
XPath for
expression;
Constructs that have alternatives among their operands, such as
an XPath if
expression;
Constructs that navigate relative to the context item, such as axis steps;
Constructs with implicit inputs, such as the context item
expression .
(dot);
Constructs that change the focus, such as a filter expression;
Constructs that invoke functions or templates.
In the same way as the type of the context item can be determined for any construct C by reference to the type of the construct that establishes the context for the evaluation of C, so the posture of the context item C can be determined by reference to the posture of the construct that establishes the context.
The context posture of a construct C is the first of the following that applies:
If the focus-setting container of
C is an xsl:function
declaration, an
inline function declaration, or an xsl:on-completion
element, then the context posture is roaming.
Note:
This is essentially an error case; expressions that depend on the context item should not normally appear within these constructs.
If the focus-setting container of
C is an xsl:stream
instruction, then the
context posture is striding.
If the focus-setting container of
C is a template rule whose mode is declared with
streamable="yes"
, then the context posture is
striding.
If the focus-setting container of C is a pattern, then the context posture is striding.
If the focus-setting container of
C is an xsl:attribute-set
declaration with the attribute streamable="yes"
, then
the context posture is striding.
If the focus-setting container is any
other declaration, for example a global variable
declaration, a named template, or a template rule or
attribute set that does not specify streamable="yes"
,
then the context posture is roaming.
Otherwise, the context posture is the posture of the controlling operand of the focus-setting container of C.
[Definition: Every construct has a sweep, which is a measure of the extent to which the current position in the input stream moves during the evaluation of the expression. The sweep is one of: motionless, consuming, or free-ranging .] This list of values is ordered: a free-ranging expression has wider sweep than a consuming expression, which has wider sweep than a motionless expression.
[Definition: A motionless construct is any construct deemed motionless by the rules in this section (19 Streamability).] Informally, a motionless construct is one that can be evaluated without changing the current position in the input stream.
Note:
The context item expression .
is classified as
motionless; however a construct that uses .
as an
operand (for example, string(.)
) might be consuming. The
streamability rules effectively consider expressions such as
.
within the context of the containing construct.
[Definition: A consuming construct is any construct deemed consuming by the rules in this section (19 Streamability).] Informally, a consuming construct is one whose evaluation requires repositioning of the input stream from the start of the current node to the end of the current node.
[Definition: A free-ranging construct is any construct deemed free-ranging by the rules in this section (19 Streamability).] Informally, a free-ranging construct is one whose evaluation may require access to information that is not available from the subtree rooted at the current node, together with information about ancestors of the current node and their attributes.
This section defines the properties of every kind of construct that may appear in a stylesheet. It identifies the operand roles and their usage, and it gives the rules that define the posture and sweep of the construct. In cases where the general streamability rules apply, there is still an entry for the construct in order to define its operands and their usages, since this information is needed by the general rules.
The following sections describe this categorization for each kind of construct:
Sequence constructors: see 19.8.3 Classifying Sequence Constructors
Instructions: see 19.8.4 Classifying Instructions
Attribute sets: see 19.8.5 Classifying Attribute Sets
Value templates: see 19.8.6 Classifying Value Templates
Expressions: see 19.8.7 Classifying Expressions
Patterns: see 19.8.9 Classifying Patterns
Calls to built-in functions: see 19.8.8 Classifying Calls to Built-In Functions
[Definition: Many constructs share the same streamability rules. These rules, referred to as the general streamability rules, are defined here.]
Examples of constructs that use these rules are: an arithmetic
expression, an attribute value template, a
sequence constructor, the xsl:value-of
instruction, and
a call to the doc
FO30
function.
The rules determine both the posture and sweep of a construct. To determine the posture and sweep of a construct C, assuming these general rules are applicable to that kind of construct:
For each operand of C:
Establish:
The static type T of the operand (see 19.2 Determining the Static Type of a Construct).
The sweep S and posture P of the operand (by applying the rules in this section 19.8 Classifying Constructs to that operand, recursively).
The operand usage U corresponding to the role of the operand within C (from the information in this section 19.8 Classifying Constructs).
Compute the adjusted sweep S' of the operand by taking the first of the following that applies:
If S is free-ranging or P is roaming, then S' is free-ranging. (In this case the posture and sweep of C are roaming and free-ranging, regardless of any other operands.)
If P is grounded, then S' is S.
Otherwise (P is not grounded, which implies that the operand is capable of returning streamed nodes), compute S' as follows:
Compute the adjusted usage U' as follows:
If U is absorption and T is a childless
node kind (text()
, attribute()
,
comment()
, processing-instruction
, or
namespace-node()
), then U' is inspection.
Note:
This is because the entire subtree of such a node is available without reading further data from the input stream.
Otherwise, U' is U.
Compute the adjusted sweep S' from the table below:
| Posture (P) | Adjusted Usage (U') | |||
|---|---|---|---|---|
| Absorption | Inspection | Transmission | Navigation | |
| Climbing | Free-ranging | S | S | Free-ranging |
| Striding | Consuming | S | S | Free-ranging |
| Crawling | Free-ranging | S | S | Free-ranging |
[Definition: An operand is potentially consuming if either or both of the following conditions applies:]
The operand usage is transmission and the operand is not grounded.
Having computed the adjusted sweep S'(o) of each operand o, the posture and sweep of C are the first of the following that applies:
If C has no operands, then grounded and motionless.
If any operand o has an adjusted sweep S'(o) of free-ranging, then roaming and free-ranging.
If more than one operand is potentially consuming, then:
If all these operands form part of a choice operand group, then the posture of C is the combined posture of the operands in this group, and the sweep of C is the widest sweep of the operands in this group
Otherwise, roaming and free-ranging.
If exactly one operand o is potentially consuming, then:
If o is a higher-order operand of C, then roaming and free-ranging.
If the operand usage of o is absorption or inspection, then grounded and consuming.
If the posture of o is crawling and C
is a function call of a function whose signature indicates a return
type with a maximum cardinality of one (for example a call on
head
FO30
or exactly-one
FO30),
then striding and the adjusted sweep of o.
Otherwise (the operand usage of o is transmission), the posture and adjusted sweep of o.
Otherwise (all operands are motionless) grounded and motionless.
Note:
The rules ensure that if more than one operand is consuming, that is, if more than one operand reads the subtree of the context node in a way that would cause the current position of the input stream to change, then the construct is not streamable.
The rules also prevent multiple streamed nodes being returned in
the result of an expression unless they arise from the same axis
traversal. For example, the expression count((@*, *))
is not streamable. The same applies to if (X) then @name else
name
. This is to make static analysis possible: the posture
needs to be statically determined to ensure that streaming does not
fail at execution time. It is permitted, however, for streamed
nodes to be mixed in a sequence with non-streamed nodes or with
atomic values; in this case the posture of the result will be that
of the streamed nodes.
This section provides some examples of how the general streamability rules operate. In each example, the emphasis is on the outermost construct shown; explanations for how the sweep and posture of its operands are derived are not given, though in many cases they are explained in earlier examples.
The examples assume that the context item type for evaluation of the expression shown is an element node, and that its posture is striding.
2 + 2
is grounded and motionless, because both the
operands are grounded and motionless.
price * 2
is grounded and consuming, because one of
the operands is consuming and the relevant operand usage is
absorption.
price - discount
is roaming and free-ranging,
because both the operands are consuming (and they are not members
of a parallel operand group).
price * @discount
is grounded and consuming. The
first operand is consuming and the corresponding operand usage is
absorption, while the second operand is motionless, again with an
operand usage of absorption, and its item type is attribute() which
changes the effective usage to inspection.
a/b/c
is striding and consuming. This is determined
not by the general streamability rules, but by the rules for path
expressions in <IP_ADDRESS> Streamability of
Path Expressions.
a//c
is crawling and consuming. This is similarly
determined by the rules for path expressions in <IP_ADDRESS> Streamability of
Path Expressions.
count(a/b/c)
is grounded and consuming, because the
operand (the argument to the count function) is striding and
consuming (see earlier example) and the operand usage is
inspection.
sum(a/b/c)
is grounded and consuming, because the
operand (the argument to the count function) is striding and
consuming (see earlier example) and the operand usage is
absorption.
count(a//c)
is grounded and consuming, because the
operand (the argument to the count function) is crawling and
consuming (see earlier example) and the operand usage is
inspection.
sum(a//c)
is roaming and free-ranging, because the
operand (the argument to the count function) is crawling and
consuming (see earlier example) and the operand usage is
inspection. The reason this cannot be streamed is that the
c
elements might have overlapping subtrees.
"Q{" || namespace-uri(.) || "}" || local-name(.)
is
grounded and motionless. The two literal operands are grounded and
motionless because they have no operands; the two function calls
are grounded and motionless because they have a single operand that
is striding and motionless, with an operand usage of
inspection.
copy-of(.)/head/following-sibling::*
is grounded
and consuming. The first operand copy-of(.)/head
is
grounded and consuming because, under the rules in <IP_ADDRESS> Streamability of
Path Expressions, its first operand copy-of(.)
is grounded and consuming. This in turn is because .
is striding and motionless, and the operand usage is
absorption.
distinct-values((., @code))
is roaming and
free-ranging. Although it is not difficult to identify a strategy
for evaluating this in a streaming manner, the static analysis
rules make an expression free-ranging if it has two operands with
different posture. This is because in general this prevents
streamability being determined statically.
if ($discounted) then price else discounted-price
is striding and consuming, because the two branches of the
conditional are both striding and consuming, and they form an
choice operand group with usage
transmission.
if ($gratis) then 0 else price else
is striding and
consuming because there is only one consuming operand (the fact
that it is part of a choice operand group
does not affect the reasoning).
count((author, editor))
is roaming and
free-ranging. The first argument to the count
function
is an expression with two operands, both having usage=transmission,
and neither being grounded.
count((author | editor))
is grounded and consuming.
A union expression is not subject to the general streamability
rules; it has its own rules, defined in <IP_ADDRESS> Streamability of
union, intersect, and except expressions, which establish
in this case that the argument to the count
FO30
is crawling and consuming. The count
FO30
function does follow the general streamability rules, with an
operand usage of inspection: under rule 1(b)(iii)(B) the
adjusted sweep is consuming, and rule 2(d)(iii) then applies.
('{', author, '}')
is striding and consuming.
Exactly one operand is consuming; it has usage transmission, so the result has the posture
and sweep of that operand. (The formal analysis treats comma as a
binary operator, but the same result can be obtained by treating
the content of the parenthesized expression as an expression with
three operands.)
The posture and sweep of a sequence constructor are determined by the general streamability rules.
The operand roles for a sequence constructor are:
The contained instructions. The operand usage for these operands is transmission.
Any text value templates appearing in text nodes within the sequence constructor, if text value templates are enabled. The operand usage for these operands is absorption.
Note:
Some consequences of these rules are:
An empty sequence constructor is motionless, and its posture is grounded.
A sequence constructor containing a single instruction has the same sweep and posture as that instruction.
Note:
This means that sequence constructors containing a single instruction can usefully be dropped from the construct tree.
Informally, a sequence constructor is not streamable if it contains more than one instruction that moves the position of the input stream.
Instructions within a sequence constructor are further classified to control the use of accumulator functions:
[Definition: A motionless instruction having no consuming instruction as a preceding sibling is referred to as a pre-descent instruction.]
[Definition: A motionless instruction having no consuming instruction as a following sibling is referred to as a post-descent instruction.]
In addition, the following are classified as post-descent instructions:
In the above rules, an instruction is considered to be consuming if its adjusted sweep S' is consuming, as defined by the the general streamability rules when applied to the containing sequence constructor.
Note:
This means that for templates that match text or attribute
nodes, an instruction such as <xsl:value-of
select="."/>
is not consuming, which means that all
instructions in the template rule qualify as both pre-descent and
post-descent instructions. The same can happen in a template rule
that does not access the string value or typed value of the context
item.
This section describes how instructions are classified with respect to their streamability. The criteria are given first for literal result elements and extension instructions,, then for each XSLT instruction, listed alphabetically.
The posture and sweep of a literal result element follow the general streamability rules. The operand roles and their usages are:
The contained sequence constructor (usage absorption)
Any expressions contained in attribute value templates among the literal result element's attributes (usage absorption)
Any attribute sets named in the
xsl:use-attribute-sets
attribute (usage absorption).
For a processor that recognizes an extension instruction, the posture and sweep of the instruction are implementation-defined.
For a processor that does not recognize an extension instruction, the posture and sweep of the instruction are determined by applying the general streamability rules, The operand roles and their usages are:
The sequence constructors contained in
any xsl:fallback
children (usage transmission)
Instructions in the XSLT namespace that are present under the provisions for forwards compatible behavior are treated in the same way as unrecognized extension instructions.
Note:
These rules mean that if there is no xsl:fallback
child
instruction, the containing construct will be classified as
streamable. However, any attempt to execute the instruction will
lead to a dynamic error, so in fact, neither streamed nor
unstreamed evaluation is possible.
xsl:analyze-string
The posture and sweep of xsl:analyze-string
follow the general streamability
rules. The operand roles and their usages
are:
the select
expression (usage absorption);
the regex
attribute value template (usage absorption);
the sequence constructors contained in the xsl:matching-substring
and xsl:non-matching-substring
elements. These have usage navigation, because they can be evaluated
more than once. The context posture for
the two sequence constructors is grounded, reflecting the fact
that their context item type is xs:string
.
Note:
In practice, the sweep of the instruction will usually be the same
as the sweep of the select
expression, and its
posture
will be grounded. Exceptions occur for example if the
regex
attribute is not motionless, or if the contained
sequence constructors refer to a grouping variable bound in a
contained xsl:for-each-group
instruction.
xsl:apply-imports
The rules in this section apply also to xsl:next-match
.
The posture and sweep of these two instructions follow the general streamability rules. The operand roles and their usages are:
An implicit operand: a context item expression (.
),
with usage absorption;
The select
attribute or contained sequence constructor of each
xsl:with-param
child
element, with type-determined usage based on
the type declared in the xsl:with-param/@as
attribute,
or item()*
if absent.
xsl:apply-templates
If there is no select
attribute, the following
analysis assumes the presence of an implicit operand
select="child::node()"
.
The posture and sweep of the xsl:apply-templates
instruction are the first of the following that apply:
If the select
expression is grounded, then the
posture
and sweep of
the xsl:apply-templates
instruction follow the general
streamability rules, with the operand roles and their
usages as follows:
The select
expression (the operand usage is
irrelevant, but can be taken as absorption)
The select
expressions and contained sequence
constructors of any child xsl:with-param
elements
(usage type-determined, based on the type
in the xsl:with-param/@as
attribute, defaulting to
item()*
)
Any attribute value templates appearing in attributes of a child
xsl:sort
instruction
(usage absorption)
The select
expression or contained sequence
constructor of any xsl:sort
children, assessed with a
context posture of grounded (usage absorption).
For example, <xsl:apply-templates
select="copy-of(.)"/>
is grounded and consuming.
If there is an xsl:sort
child element, then roaming and free-ranging.
If the implicit or explicit mode
attribute
identifies a mode that is not declared with
streamable="yes"
, then roaming and free-ranging.
Note:
When mode="#current"
is specified, this is treated
as equivalent to specifying a streamable mode; although it is not
known statically what the mode will be, it is always the case that
if the template is invoked with a streamed node as the context
item, the the current mode must be a streamable mode.
Otherwise, the posture and sweep of the xsl:apply-templates
instruction follow the general
streamability rules. The operand roles and their
usages are as follows:
The (explicit or implicit) select
expression, with
usage absorption;
The select
attribute or contained sequence constructor of each
xsl:with-param
child
element, with type-determined usage based on
the type declared in the xsl:with-param/@as
attribute,
or item()*
if absent.
xsl:assert
The posture and sweep of xsl:assert
follow the general streamability rules.
The operand roles and their usages
are as follows:
The test
expression (usage inspection)
The select
expression (usage absorption)
The contained sequence constructor (usage absorption).
xsl:attribute
The posture and sweep of xsl:attribute
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The name
attribute value template (usage absorption)
The namespace
attribute value template (usage
absorption)
The select
expression (usage absorption)
The separator
attribute value template (usage
absorption)
The on-empty
expression (usage absorption)
The contained sequence constructor (usage absorption).
xsl:break
The posture and sweep of xsl:break
follow the general streamability rules.
The operand roles and their usages
are as follows:
The select
expression (usage transmission)
The contained sequence constructor (usage transmission).
xsl:call-template
The posture and sweep of xsl:call-template
follow
the general streamability rules.
The operand roles and their usages
are as follows:
Unless the referenced template has a child xsl:context-item
element
with the attribute use="prohibited"
, there is an
implicit operand, a context item expression (.
): its
operand usage is the type-determined usage based on the
type declared in the xsl:context-item/@as
attribute of
the target named template, defaulting to item()*
if
absent.
The select
expression or sequence constructor
content of any contained xsl:with-param
child
element: its operand usage is the type-determined usage based on the
type declared in the xsl:with-param/@as
attribute, or
the xsl:param/@as
attribute of the corresponding
parameter on the target named template, whichever is more
restrictive, defaulting to item()*
if both are
absent.
Note:
Calling xsl:call-template
will
usually make stylesheet code unstreamable if a streamed node is
passed explicitly or implicitly to the called template, unless it
is atomized by declaring the expected type to be atomic.
xsl:choose
The posture and sweep of xsl:choose
follow the general streamability rules.
The operand roles and their usages
are as follows:
The test
attribute of contained xsl:when
elements (usage inspection).
The sequence constructors contained within xsl:when
and xsl:otherwise
child elements
(usage transmission). These sequence constructor
operands form a choice operand group.
Note:
The effect is to allow any of the following:
Every sequence constructor in an xsl:when
or xsl:otherwise
branch may read
the input stream. In this situation the test
expressions must be motionless.
Alternatively, the first test
expression may
consume the input stream, in which case the sequence constructors
(and any subsequent test
expresssions) must be
motionless.
xsl:comment
The posture and sweep of xsl:comment
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The select
expression (usage absorption)
The contained sequence constructor (usage absorption).
xsl:copy
The posture and sweep of xsl:copy
follow the general streamability rules.
The operand roles and their usages
are as follows:
The expression in the select
attribute, defaulting
to a context item expression (.
) (usage inspection)
The contained sequence constructor (usage absorption), assessed
with context posture and context item type
based on the select
expression if present, or the
outer focus otherwise.
Any attribute-sets named in the
use-attribute-sets
attribute (usage absorption)
The expression contained in the on-empty
attribute,
if present (usage absorption).
xsl:copy-of
The posture and sweep of xsl:copy-of
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The select
expression (usage absorption).
xsl:document
The posture and sweep of xsl:document
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The contained sequence constructor (usage absorption).
xsl:element
The posture and sweep of xsl:element
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The name
attribute value template (usage absorption)
The namespace
attribute value template (usage
absorption)
The on-empty
expression (usage absorption)
The attribute sets named in the use-attribute-sets
attribute (usage absorption)
The contained sequence constructor (usage absorption).
xsl:evaluate
The posture and sweep of xsl:evaluate
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The xpath
expression (usage absorption)
The context-item
expression (usage navigation)
The with-params
expression (usage navigation)
The base-uri
attribute value template (usage
absorption)
The namespace-context
expression (usage inspection)
The select
attributes and contained sequence constructors of any
xsl:with-param
child
elements (usage type-determined, based on the
type in the xsl:with-param/@as
attribute, defaulting
to item()*
)
Note:
In practice, code containing an xsl:evaluate
instruction will
usually be streamable provided that streamed nodes are not passed
to the dynamic expression either as the context item or as the
value of a parameter.
xsl:for-each
The posture and sweep of the xsl:for-each
instruction are
the first of the following that applies:
If the select
expression is grounded, then the
posture
and sweep of
the xsl:for-each
instruction follow the general
streamability rules, with the operand roles and their
usages as follows:
The select
expression (the operand usage is
irrelevant, but can be taken as inspection)
The contained sequence constructor (usage transmission). This is a higher-order operand; its context posture is grounded.
Any attribute value templates appearing in attributes of a child
xsl:sort
instruction
(usage absorption)
The select
expression or contained sequence
constructor of any xsl:sort
children, assessed with a
context posture of grounded (usage absorption).
These are higher-order operands; their context
posture is grounded.
If there is an xsl:sort
child element, then roaming and free-ranging.
Otherwise:
The posture of the instruction is the posture of the
contained sequence constructor, assessed with
the context posture and context item
type set to the posture and type of the select
expression.
The sweep
of the instruction is the wider of the sweep of the select
expression and the sweep of the contained sequence constructor.
Note:
The ordering of sweep values is in increasing order: motionless, consuming, free-ranging.
xsl:for-each-group
The posture and sweep of the xsl:for-each-group
instruction are the first of the following that applies:
If the select
expression is grounded, then the
posture
and sweep of
the xsl:for-each-group
instruction follow the general
streamability rules, with the operand roles and their
usages as follows:
The select
expression (the operand usage is
irrelevant, but can be taken as inspection)
The collation
attribute value template (usage
absorption)
Any attribute value templates appearing in attributes of a child
xsl:sort
instruction
(usage absorption)
The group-by
or group-adjacent
expression, assessed with a context posture of
grounded (usage absorption).
The select
expression or contained sequence
constructor of any xsl:sort
children, assessed with a
context posture of grounded (usage absorption).
The group-starting-with
or
group-ending-with
patterns if present; these are
higher-order operands with usage
inspection.
If there is a group-by
attribute, then roaming and
free-ranging.
If there is a group-adjacent
attribute that is not
motionless, then roaming and free-ranging.
If there is an xsl:sort
child element, then roaming and free-ranging.
If there is no bind-group
attribute, then roaming and
free-ranging.
If there is a group-adjacent
attribute but no
bind-grouping-key
attribute, then roaming and free-ranging.
Otherwise:
The posture of the instruction is the posture of the
contained sequence constructor, assessed with
the context posture and context item
type set to the posture and type of the select
expression.
The sweep
of the instruction is the wider of the sweeps of the select
expression and the contained sequence constructor,
where the ordering of increasing width is motionless, consuming,
free-ranging.
Note:
The above rules do not explicitly mention any constraints on the
presence or absence of a variable reference to the variable bound
in the bind-group
attribute of the xsl:for-each-group
instruction. In practice, however, this plays an important role. In
the most common case, the select
expression of
xsl:for-each-group
is likely to be striding, for example an expression that selects
all the children of a given element. If the instruction binds a
variable $group
using the bind-group
attribute, then any reference to this variable will ordinarily be
striding and consuming, which is consistent
with streaming provided there is only one such reference, and if it
appears in a suitable context (for example, not within a
predicate). If there is more than one reference to the
grouping variable, or if it appears in an unsuitable context (for
example, within a predicate), then this will have the same effect
as multiple appearances of other consuming expressions: the
construct as a whole will be free-ranging. These
rules are not spelled out explicitly, but rather emerge as a
consequence of the general streamability rules.
xsl:fork
The posture and sweep of xsl:fork
are the first of the
following that applies:
If there are no child xsl:sequence
instructions,
then grounded and motionless.
If there is exactly one child xsl:sequence
instruction that
is not grounded and motionless, then the posture and
sweep of that
instruction.
If any of the child xsl:sequence
instructions is
roaming
or free-ranging, then roaming and free-ranging.
If the posture of any of the child xsl:sequence
instructions is
not grounded, then roaming and free-ranging.
Note:
The effect of the rules is that each of the child xsl:sequence
instructions can
independently consume the streamed input document, provided that
the result of each child instruction is grounded.
Thus the following example is streamable:
<xsl:fork> <xsl:sequence select="copy-of(author)"/> <xsl:sequence select="copy-of(editor)"/> </xsl:fork>
While the following is not streamable:
<xsl:fork> <xsl:sequence select="author"/> <xsl:sequence select="editor"/> </xsl:fork>
This is because the latter example attempts to return a sequence of streamed nodes in an order which might not be document order.
The only case where xsl:fork
is permitted to return
streamed nodes is in the case where only one of the xsl:sequence
instructions is
consuming (in which case the xsl:fork
instruction is
pointless).
xsl:if
The posture and sweep of xsl:if
follow the general streamability rules.
The operand roles and their usages
are as follows:
The test
expression (usage inspection)
The contained sequence constructor (usage transmission).
xsl:iterate
The posture and sweep of the xsl:iterate
instruction are the
first of the following that applies:
If the select
expression is grounded, then the
posture
and sweep of
the xsl:iterate
instruction follow the general
streamability rules, with the operand roles and their
usages as follows:
The select
expression (the operand usage is
irrelevant, but can be taken as inspection)
The select
expression or contained sequence
constructor of any xsl:param
children (usage
navigation)
The sequence constructor contained within the xsl:iterate
instruction itself,
assessed with its content item type and context posture
based on the select
expression (usage transmission)
The select
expression or contained sequence
constructor of any child xsl:on-completion
element, assessed with a content item type of xs:error
and a context posture of roaming to reflect the fact
that any attempt to reference the context item within the xsl:on-completion
element
is an error (usage transmission)
Otherwise:
The posture of the instruction is the posture of the
contained sequence constructor, assessed with
the context posture and context item
type set to the posture and type of the select
expression.
The sweep of the instruction is the wider of the sweeps of the two operands, where the ordering of increasing width is motionless, consuming, free-ranging.
Note:
If any xsl:break
or
xsl:next-iteration
instructions appear within the sequence constructor, their
posture
and sweep
will be assessed in the course of evaluating the posture and sweep of the sequence
constructor, by reference to the rules in <IP_ADDRESS> Streamability of
xsl:break and <IP_ADDRESS> Streamability of
xsl:next-iteration respectively.
xsl:map
The posture and sweep of the xsl:map
instruction are determined
by the first of the following that applies:
If the sequence constructor within the instruction consists
exclusively of xsl:map-entry
instructions
(and xsl:fallback
instructions, which are ignored), and if none of those xsl:map-entry
children is
roaming
or free-ranging, then the posture of the xsl:map
instruction is grounded and the
sweep is the
widest sweep of the xsl:map-entry
children.
Otherwise, the posture and sweep of the xsl:map
instruction are the posture
and sweep of the contained sequence
constructor.
Note:
See discussion in 21.1.5 Maps and Streaming.
The effect of the rules is that it is possible to compute multiple map entries in a single pass of the streamed input document. For example, the following is streamable:
<xsl:map> <xsl:map-entry key="'authors'" select="copy-of(author)"/> <xsl:map-entry key="'editors'" select="copy-of(editor)"/> </xsl:map>
The call on copy-of
is
necessary to ensure that the content of the map entry is grounded;
it is not possible to create a map whose entries contain references
to streamed nodes.
xsl:map-entry
The posture and sweep of xsl:map-entry
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The key
expression (usage absorption)
The select
expression (usage navigation)
Note:
This effectively means that the select
expression
must not return nodes from a streamed input document.
The contained sequence constructor (usage navigation).
xsl:merge
If all xsl:merge-source
children
are motionless then the instruction is motionless.
Otherwise, the instruction is free-ranging.
Note:
The xsl:merge
instruction will often process its input using streaming, but the
rule here is concerned with the sweep of the instruction with respect to the
document containing the context node, which will not usually be one
of the primary inputs to the merging process. A merge operation
that processes several input documents in a streaming manner might
thus be classified as free-ranging with respect to the principal
source document of the transformation.
A more ambitious implementation might attempt to recognize the case where one of the merge sources involves consuming a subtree of the principal source document: that is, the case where one merge source is a consuming expression and the other sources are motionless.
xsl:message
The posture and sweep of xsl:message
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The select
expression (usage absorption)
The terminate
attribute value template (usage
absorption)
The contained sequence constructor (usage absorption).
xsl:namespace
The posture and sweep of xsl:namespace
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The name
attribute value template (usage absorption)
The select
expression (usage absorption)
The contained sequence constructor (usage absorption).
xsl:next-iteration
The posture and sweep of xsl:next-iteration
follow the general streamability
rules. The operand roles and their usages
are as follows:
The select
expression or sequence constructor content of any
contained xsl:with-param
child
element: its operand usage is the type-determined usage based on the
type declared in the xsl:with-param/@as
attribute, or
the xsl:param/@as
attribute of the corresponding
parameter on the containing xsl:iterate
instruction,
whichever is more restrictive, defaulting to item()*
if both are absent.
xsl:next-match
The rules are the same as for xsl:apply-imports
: see
<IP_ADDRESS>
Streamability of xsl:apply-imports.
xsl:number
The posture and sweep of xsl:number
follow the general streamability rules.
The operand roles and their usages
are as follows:
The value
attribute if present (usage absorption)
The select
attribute if present (usage navigation)
The attribute value templates in the format
,
lang
, letter-value
, ordinal
,
start-at
, grouping-separator
, and
grouping-size
attributes (usage absorption)
The from
and count
patterns if
present; these are higher-order operands with
usage inspection.
Note:
The effect of these rules is that xsl:number
can be used for
formatting of numbers supplied directly, and for numbering of nodes
in a non-streamed document, but cannot be used for numbering
streamed nodes.
In practice the rules depend very little on the
from
and count
patterns. This is because
when the instruction is applied to a streamed node, the instruction
will be free-ranging regardless of these patterns;
while if it is applied to a grounded node or atomic value, the
instruction will be motionless regardless of the values of these
patterns. The only restriction is that the patterns must not
reference a grouping variable.
xsl:perform-sort
The posture and sweep of xsl:perform-sort
follow
the general streamability rules.
The operand roles and their usages
are as follows:
The expression in the select
attribute: usage
navigation (because order is not
preserved)
The expressions in the attribute value templates of xsl:sort
child elements: usage
absorption
The expression in the select
attribute or
contained sequence constructor in child xsl:sort
child elements, with
usage absorption, assessed with context posture based on the
expression in the xsl:perform-sort/@select
attribute.
Note:
In practice, the xsl:perform-sort
instruction cannot be used to sort nodes from the streamed input
document, but it can be used to sort atomic values or grounded nodes,
for example a copy of nodes from the streamed document made using
the copy-of
function.
xsl:processing-instruction
The posture and sweep of xsl:processing-instruction
follow the general streamability
rules. The operand roles and their usages
are as follows:
The name
attribute value template (usage absorption)
The select
expression (usage absorption)
The contained sequence constructor (usage absorption).
xsl:result-document
The posture and sweep of xsl:result-document
follow the general streamability
rules. The operand roles and their usages
are as follows:
The href
attribute value template (usage absorption)
The attribute value templates containing serialization properties (usage absorption)
The contained sequence constructor (usage absorption).
xsl:sequence
The posture and sweep of xsl:sequence
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The select
attribute value template (usage
transmission)
The contained sequence constructor (usage transmission).
xsl:stream
Note:
The concern here is with the impact of xsl:stream
on any streaming
template, or ancestor xsl:stream
instruction, and not
with the streamed processing of the document accessed using the
xsl:stream/@href
attribute.
The streamability of the document opened by the xsl:stream
instruction is not
assessed using the rules in this section; it depends only on the
streamability properties of the contained sequence constructor, as
described in 18.1 The xsl:stream
Instruction
The posture and sweep of xsl:stream
are the first of the
following that applies:
If the contained sequence constructor contains, at any depth, a
variable reference whose binding is a bind-group
attribute of an xsl:for-each-group
or
xsl:merge
instruction
that is itself an ancestor of the xsl:stream
instruction, then
roaming
and free-ranging.
Otherwise, the posture is grounded and the sweep is the sweep of the href
attribute value template.
Note:
The effective prohibition on grouping variable references is
largely to avoid complicating the analysis. It means that posture
and sweep for the constructs within xsl:stream
need to be computed
only with respect to the xsl:stream
instruction itself,
and not with respect to the containing template, or an outer
xsl:stream
instruction.
xsl:text
The posture and sweep of xsl:text
follow the general streamability rules.
There are no operands.
Note:
The instruction is therefore grounded and motionless.
xsl:try
The sweep of the instruction is the first of the following that applies:
If the select
expression and/or sequence
constructor of the xsl:catch
element are motionless,
then the sweep of the select
expression and/or
sequence constructor of the xsl:try
element (whichever is
present);
Otherwise, free-ranging.
xsl:value-of
The posture and sweep of xsl:value-of
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The select
expression (usage absorption)
The separator
attribute value template (usage
absorption)
The contained sequence constructor (usage absorption).
xsl:variable
The posture and sweep of xsl:variable
follow the
general streamability rules.
The operand roles and their usages
are as follows:
The select
expression (usage navigation)
The contained sequence constructor (usage navigation).
Note:
The effect of the initialization expression having usage navigation is that it is not possible in streamable constructs to bind a variable to a node in a streamed document.
The general streamability rules apply to attribute sets. The operand roles and their usages are:
Any xsl:attribute
instruction contained in any of the xsl:attribute-set
declarations making up the attribute set. (Usage transmission)
Any attribute set referenced by a
use-attribute-sets
attribute in any of the
xsl:attribute-set
declarations making up the attribute set. (Usage transmission)
The sweep of an attribute set is determined using the general rules in 19.8.1 General Rules for Streamability.
Note:
Attribute sets will always be grounded, because they return newly constructed attribute nodes.
Attribute sets will very often be motionless, but if they access the context item, they may be consuming or free-ranging.
Because attribute sets can be overridden in another package, the
streamability of a construct such as an xsl:element
instruction
containing a use-attribute-sets
attribute is based on
the declared streamability of the named attribute sets, as defined
by the streamable
attribute of the xsl:attribute-set
element. If streamable="yes"
is specified, then there
is a requirement that any overriding attribute set should also
specify streamable="yes"
, and a streaming processor is
required to check that an attribute set containing such a
declaration does in fact satisfy the streamability rules.
A value template (that is, an attribute value template or
text value template) is a construct
whose operands are the expressions contained within curly braces.
The required type for this operand role is xs:string
and the usage is absorption.
The sweep and posture of a value template are determined using the general rules in 19.8.1 General Rules for Streamability.
If there are no expressions contained within curly braces, the value template is motionless.
XPath expressions are classified using the rules in this section.
In the analysis that follows, expressions are classified
according to the most specific production rule that they match for
which there is an entry in this section. For example, the
expression 3
satisfies the productions
NumericLiteral
, Literal
, and
ArithmeticExpression
; the most specific of these for
which there is an entry in this section is Literal
. A
production P is considered more specific than a
production Q (Q ≠ P) if every
expression that matches P also matches Q.
The production rules for different kinds of expression are listed (with their names and numbers) in the order in which they appear in Appendix A.1 of the XPath 3.0 specification.
Many expressions can be analyzed using the general streamability rules.
These are indicated in the table below by means of a simple
proforma in which the operand roles are represented by a short
code (A = absorption, I = inspection, T = transmission, N = navigation). For example
the proforma A + A
indicates that for an arithmetic
expression, both operands have operand usage absorption,
while I or I
indicates that for an or
expression, both operands have operand usage inspection.
For expressions where further explanation is needed, the table
contains a link to the relevant section.
| Construct | Proforma or Reference to Detailed Rules | Further Information |
|---|---|---|
| Expr [6] | T, T |
|
| ForExpr [8] | See <IP_ADDRESS> Streamability of for expressions | |
| LetExpr [11] | let $var := N return
T |
Binding of variables to streamed nodes is not allowed. |
| QuantifiedExpr [14] | See <IP_ADDRESS> Streamability of Quantified Expressions | |
| IfExpr [15] | if (I) then T else
T |
The then-clause and else-clause form a choice operand group with usage transmission |
| OrExpr [16] | I or I |
|
| AndExpr [17] | I and I |
|
| StringConcatExpr [19] | A || A |
|
| RangeExpr [20] | A to A |
|
| AdditiveExpr [21] | A + A , A -
A |
|
| MultiplicativeExpr [22] | A * A , A div
A , etc |
|
| UnionExpr [23] | See <IP_ADDRESS> Streamability of union, intersect, and except expressions | |
| IntersectExceptExpr [24] | See <IP_ADDRESS> Streamability of union, intersect, and except expressions | |
| InstanceOfExpr [25] | I instance of TYPE |
|
| TreatExpr [26] | T treat as TYPE |
|
| CastableExpr [27] | A castable as TYPE |
|
| CastExpr [28] | A cast as TYPE |
|
| UnaryExpr [29] | +A , -A |
|
| GeneralComp [31] | A = A , A <
A , A != A , etc |
|
| ValueComp [32] | A eq A , A lt
A , A ne A , etc |
|
| NodeComp [33] | I is I , I
<< I , I >> I |
|
| SimpleMapExpr [34] | See <IP_ADDRESS> Streamability of Simple Mapping Expressions | |
| PathExpr [35] | See <IP_ADDRESS> Streamability of Path Expressions | |
| RelativePathExpr [36] | See <IP_ADDRESS> Streamability of Path Expressions | |
| AxisStep [38] | See <IP_ADDRESS> Streamability of Axis Steps | |
| ForwardStep [39] , ReverseStep [42] | See <IP_ADDRESS> Streamability of Axis Steps | |
| PostfixExpr [48]: Filter Expression | See <IP_ADDRESS> Streamability of Filter Expressions | |
| PostfixExpr [48]: Dynamic Function Call | See <IP_ADDRESS> Streamability of Dynamic Function Calls | |
| Literal [53] | There are no operands, so the construct is grounded and motionless | |
| VarRef [55] | See <IP_ADDRESS> Streamability of Variable References | |
| ParenthesizedExpr [57] | (T) |
|
() |
There are no operands, so the construct is grounded and motionless | |
| ContextItemExpr [58] | See <IP_ADDRESS> Streamability of the Context Item Expression | |
| FunctionCall [59] | See <IP_ADDRESS> Streamability of Function Calls | |
| NamedFunctionRef [63] | See <IP_ADDRESS> Streamability of Named Function References | |
| InlineFunctionExpr [64] | See <IP_ADDRESS> Streamability of Inline Function Declarations | |
| MapExpr [202] | See <IP_ADDRESS> Streamability of map expressions |
for
expressionsWriting the expression as for $v in S return R
, the
two operand roles are S and R.
The posture and sweep are determined by the first of the following that applies:
If R is not grounded, then roaming and free-ranging.
Otherwise, the general streamability rules apply. The operand roles are:
The in
expression (S
). This has
usage navigation.
The return
expression (R
). This is a
higher-order operand with usage
transmission.
Note:
Expressions of the form for $i in 1 to 3 return
$i*2
, where there is no reference to a streamed node, are
clearly streamable.
The in
expression can also be consuming, for
example for $e in copy-of(emp)
return $e/salary.
The rule that R must be grounded prevents the
variable being bound to a node in a streamed document. This
disallows expressions of the form for $x in child::section
return $x/para
, because this requires data flow analysis
(tracing from the binding of a variable to its usages), rather than
purely syntactic analysis. Some implementations may be able to
stream such constructs.
The fact that the return clause is a higher-order operand
prevents it from being a consuming expression, for example
for $i in 1 to 3 return salary
. Use of a motionless
expression that accesses streamed nodes is however allowed, for
example for $i in 1 to 3 return
name(ancestor::x[$i])
.
Writing the expression as some|every $v in S satisfies
C
, the two operand roles are S and
C.
The posture and sweep are determined by the first of the following that applies:
If C is not motionless, then roaming and free-ranging.
if
expressionsWriting the expression as if (C) then T else E
,
there are three operand roles: C, T, and
E. The usage of C is inspection,
while the usage of T and E is
transmission. Operands T and
E form a choice operand group, meaning
that they can both consume the input stream, provided they have
consistent posture. The general streamability rules
apply.
union
, intersect
, and except
expressionsThe posture and sweep are the first of the following that applies:
If either of the two operands is free-ranging, then roaming and
free-ranging (Example: . |
following-sibling::*
).
If either of the two operands is grounded and motionless,
then the posture and sweep of the other operand (Example: . |
doc('abc.com')//x
)
If both operands are climbing and motionless, then climbing and
motionless (Example: @x | @y
)
If both operands are striding or crawling, then crawling and the wider of the
sweeps of the two operands (Example: * | */*
).
Otherwise, roaming and free-ranging (Example:
name | @name
).
Note:
Essentially the principle is that if both operands are
streamable, then the result is streamable (this assumes an
evaluation strategy where both operands are evaluated during the
same pass of the streamed input document, and the results merged).
But there are caveats because of the need for static streamability
analysis of the result. This prevents constructs such as .. |
*
that have heterogeneous posture.
Where the two operands are both striding, there are cases where
an implementation could determine that the result is also striding: for
example (author | editor)
. In general, however, the
combination of two striding operands may produce a sequence of
nodes that have overlapping subtrees (consider author |
author/name
), so the result is classified as crawling.
The expression (author | editor)
, although it is
not striding, can be rewritten in the form
*[self::author or self::editor]
, which is striding.
The mapping operator !
is treated as a
left-associative binary operator, so the expression
a!b!c
is processed as (a!b)!c
.
The posture and sweep of the expression are the posture and sweep of the right-hand operand, assessed with a context posture and type set to the posture and type of the first operand.
The streamability analysis applies after the expansion of the
//
pseudo-operator to
/descendant-or-self::node()/
, and after expanding
..
to parent::node()
, @X
to
attribute::X
, and an omitted axis to
child::
.
Following the rules in XPath, a leading "/"
is
converted to (root(self::node()) treat as
document-node())/
(with the final "/"
omitted
for the expression "/"
on its own). This is followed
by a rewrite of the call on root
FO30,
as described in <IP_ADDRESS>
Streamability of the root function.
Note:
Taken together, these rewrites have the effect that a path
expression such as //a
is streamable only if the
statically-determined context item type is
document-node()
, which will be the case for example
immediately within xsl:stream
, or in a template
rule with match="/"
.
A RelativePathExpr
with more than two operands
(such as a/b/c
) is taken as a tree of binary
expressions (that is, (a/b)/c
). This prevents some
optimizations which are possible if the
RelativePathExpr
is considered as a whole: these
optimizations should be applied by rewriting the tree before this
analysis takes place, as described in 19.1 An Optimization: Pattern-Based
Scanning.
The posture of the expression is the posture of the right-hand operand, assessed with a context posture and type set to the posture and type of the first operand.
Note:
Examples:
If the context posture is striding, then
the posture of the expression a/b/c
is striding,
because (under the rules for AxisStep [38]) a child axis step
evaluated with striding posture creates a new striding posture.
If the context posture is striding, then
the posture of the expression a//c
is crawling,
because a descendant axis step evaluated with striding posture
creates a new crawling posture.
If the context posture is striding, then
the posture of the expression ../@status
is climbing,
because a parent axis step evaluated with striding posture creates
a new climbing posture, and an attribute axis step evaluated with
climbing posture creates a new climbing posture.
If the context posture is striding, then
the posture of the expression
copy-of(.)//a/following-sibling::*
is grounded,
because the copy-of
evaluated with striding posture creates a grounded posture, and all
subsequent axis steps leave this posture unchanged.
The sweep of the expression is the wider sweep of the two operands, where the ordering of increasing width is motionless, consuming, free-ranging.
Note:
Examples:
The sweep
of a/@code
is consuming (the wider of consuming and
motionless).
The sweep
of a/descendant::b
is consuming (the wider of
consuming and consuming).
The sweep
of ./@code
is motionless (the wider of motionless
and motionless).
The sweep
of ./a
is consuming (the wider of motionless and consuming).
The sweep
of a/following::b
is free-ranging (the wider of
consuming and free-ranging).
The sweep
of ./.
is motionless (the wider of motionless and motionless).
The sweep and posture of the expression are determined by the first of the following rules that applies:
If the context posture is grounded, then the sweep is motionless and the posture is grounded;
If the context posture is roaming, then the sweep is free-ranging and the posture is roaming;
If the statically-inferred context item type is such that the axis will always be empty (for example, applying the child axis to a text node or the parent axis to a document node), then the sweep is motionless and the posture is grounded (because the expression is statically known to return an empty sequence);
If the context posture is striding, and the axis is
descendant or descendant-or-self, and there is a predicate in the
PredicateList
that is either a numeric literal or a
reference to a variable whose declared type is numeric (for
example, descendant::title[1]
), then striding and
consuming;
If the PredicateList
contains a
Predicate
that is not motionless, then the sweep is
free-ranging and the posture is roaming;
Otherwise, the sweep and posture of the expression are as determined by the table below, based on the context posture and the choice of axis:
| Context posture | Axis | Result posture | Sweep |
|---|---|---|---|
| Grounded | any | Grounded | Motionless |
| Climbing | self, parent, ancestor-or-self, ancestor, attribute, namespace | Climbing | Motionless |
| Striding | parent, ancestor-or-self, ancestor, attribute, namespace | Climbing | Motionless |
| Striding | self | Striding | Motionless |
| Striding | child | Striding | Consuming |
| Striding | descendant, descendant-or-self | Crawling | Consuming |
| Crawling | parent, ancestor-or-self, ancestor, attribute, namespace | Climbing | Motionless |
| Crawling | self | Crawling | Motionless |
| Any other combination | Roaming | Free-ranging |
Note:
This analysis does not attempt to classify
para[title]
as a consuming expression; an
implementation might choose to do so.
For a filter expression of the form B[P]
(where
B might itself be a filter expression), the posture and
sweep are the
first of the following that applies:
If B is crawling and consuming, and B is either a numeric literal, or a reference to a variable whose declared type is numeric, then crawling and consuming
If P is motionless, then the posture and sweep of B;
Otherwise, roaming and free-ranging.
Note:
The first rule allows a construct such as
<xsl:apply-templates select="(//title)[1]"/>
,
where a crawling operand would not be guaranteed
streamable.
Note:
This section is not applicable to predicates forming part of an
axis step, such as //title[1]
, as these are not
technically filter expressions. See <IP_ADDRESS> Streamability of Axis
Steps.
For a dynamic function call such as $F(X, Y)
, the
general rule in 19.8.1
General Rules for Streamability applies. The operands of a
dynamic function call are the expression that computes the function
value itself (here $F
), and the argument expressions
(here X
and Y
).
The operand usage of the first operand is inspection, reflecting the fact that the only action needed at evaluation time is to inspect the value (if it is a node, a type error is raised).
The operand usage for the other operands (the argument expressions) is in general navigation, because it is not known how the function will make use of any supplied nodes. However, if the static type of the first operand constrains the type of the argument to be atomic, then the operand usage for that argument becomes absorption, and if it constrains it to be a function, the operand usage becomes inspection.
The sweep and posture of the variable reference V are the first of the following that apply:
If all the following conditions are satisfied:
V is a reference to a variable declared in a
bind-group
attribute of a containing xsl:for-each-group
instruction F
The path in the construct tree that connects V to the sequence constructor forming the body of F is such that no child construct is a higher-order operand of its parent
The focus-setting container of V is F
then the sweep and posture of V are the sweep and posture of the
select
expression of F.
If all the following conditions are satisfied:
V is a reference to a variable declared in a
bind-group
attribute of a containing xsl:merge
instruction
M
The path in the construct tree that connects V to the sequence constructor forming the body of M is such that no child construct is a higher-order operand of its parent
The focus-setting container of V is M
then the sweep and posture of V are the sweep and posture of the sequence constructor contained in M.
If all the following conditions are satisfied:
V is a reference to a variable declared in a
bind-source
attribute of an xsl:merge-source
child of
a containing xsl:merge
instruction M
The path in the construct tree that connects V to the sequence constructor forming the body of M is such that no child construct is a higher-order operand of its parent
The focus-setting container of V is M
then the sweep and posture of V are the sweep and posture of the sequence constructor contained in M.
Otherwise, V is roaming and free-ranging.
Note:
Informally, for streamed evaluation to be possible, a grouping
variable reference must not appear in a construct that is evaluated
repeatedly. For example, if $g
is the variable bound
to the current group, then the expression for $i in 1 to 10
return $g
would not be streamable.
Otherwise, the sweep of the expression is motionless.
Note:
These rules reflect the fact that a node in a streamed document can never be bound to a variable, except in the case where it is part of the current group of nodes bound to a grouping variable.
The posture of the expression is the context posture, and the sweep is motionless.
Note:
Although .
is intrinsically motionless, when used
in certain contexts (such as data(.)
) the containing
expression will be consuming. This arises because of the operand
usage: the argument to data
FO30
has usage absorption, and the combination of a motionless
operand with usage absorption leads to the containing expression
being consuming.
Similarly, if .
is used where the operand usage is
navigation, the containing expression will be
free-ranging.
For calls to built-in functions, see 19.8.8 Classifying Calls to Built-In Functions.
For a call to a constructor function, the 19.8.1 General Rules for Streamability apply. There is a single operand role (the argument to the function), with operand usage absorption.
For a call to a stylesheet function, the general streamability rules apply. There is one operand role for each argument in the function signature, and its operand usage is the type-determined usage based on the declared type of that argument.
If the function call is a partial function application (that is,
one or more of the arguments is given as ?
), then:
If the function is focus-dependent, then the sweep is free-ranging
Otherwise, the general
streamability rules apply. The operands of a partial
function application are the expressions actually supplied as
arguments to the function, ignoring ?
place-holders;
the corresponding operand usage is the type-determined usage based on the
declared type of that argument.
A NamedFunctionRef
is motionless, unless the
function it refers to is focus-dependent, in which case it is
free-ranging.
The sweep of the expression is the first of the following that applies:
If the body of the inline function contains a reference to a
variable defined in the bind-group
attribute of an
xsl:for-each-group
element external to the inline function, then free-ranging.
Otherwise, motionless.
The posture and sweep of a map expression are the same as the
posture
and sweep of
the equivalent xsl:map
instruction. The equivalent xsl:map
instruction is formed by
creating a sequence of xsl:map-entry
instructions,
one for each key/value pair in the map expression, where the key
expression becomes the value of xsl:map-entry/@key
,
and the value expression becomes the value of
xsl:map-entry/@select
; this sequence of xsl:map-entry
instructions is
then wrapped in an xsl:map
parent instruction.
For example, the map expression map{'red':false(),
'green':true()}
translates to the instruction:
<xsl:map> <xsl:map-entry key="'red'" select="false()"/> <xsl:map-entry key="'green'" select="true()"/> </xsl:map>
The rules for the streamability of xsl:map
appear in <IP_ADDRESS> Streamability of
xsl:map.
See also 21.1.5 Maps and Streaming.
This section describes the rules that determine the streamability of calls to built-in functions. These differ from user-written functions because it is known (defined in the specification) how nodes supplied as operands are used. Knowledge of the usage of each operand, together with the posture of the actual operands, is in most cases enough to determine the posture and sweep of the function result.
All the built-in functions are listed below. For most functions,
a simple proforma is shown that indicates the operand usage of each
argument, using the code (A = absorption, I = inspection, T = transmission, N = navigation). So, for
example, the entry fn:remove(T, A)
means that for the
function fn:remove#2
, the operand usage of the first
argument is transmission, and the operand usage of the
second argument is absorption. By reference to the general rules
in 19.8.1 General Rules
for Streamability, this demonstrates that if the
context posture is striding, the
posture and sweep of the expression sum(remove(*,1))
will be grounded
and consuming
respectively.
For functions that default one of their arguments (typically to the context item), the relevant entry shows the equivalence, and the posture and sweep can in these cases be computed by filling in the default value for the relevant argument.
Some functions do not follow the general rules, and these are listed with a link to the section where the particular rules for that function are described.
fn:abs(A)
fn:accumulator-after
– See <IP_ADDRESS> Streamability of
the accumulator-after function
fn:accumulator-before
– See <IP_ADDRESS> Streamability of
the accumulator-before function
fn:adjust-date-to-timezone(A)
fn:adjust-date-to-timezone(A, A)
fn:adjust-dateTime-to-timezone(A)
fn:adjust-dateTime-to-timezone(A, A)
fn:adjust-time-to-timezone(A)
fn:adjust-time-to-timezone(A, A)
fn:analyze-string(A, A)
fn:analyze-string(A, A, A)
fn:available-environment-variables()
fn:avg(A)
fn:base-uri()
– Equivalent to
fn:base-uri(.)
fn:base-uri(I)
fn:boolean(I)
fn:ceiling(A)
fn:codepoint-equal(A, A)
fn:codepoints-to-string(A)
fn:collation-key(A)
fn:collation-key(A, A)
fn:collection()
fn:collection(A)
fn:compare(A, A)
fn:compare(A, A, A)
fn:concat(A, A, A)
fn:contains(A, A)
fn:contains(A, A, A)
fn:copy-of()
– Equivalent to
fn:copy-of(.)
fn:copy-of(A)
fn:count(I)
fn:current
– See <IP_ADDRESS> Streamability of the
current function
fn:current-date()
fn:current-dateTime()
fn:current-group
– See <IP_ADDRESS> Streamability of the
current-group function
fn:current-grouping-key
– See <IP_ADDRESS> Streamability
of the current-grouping-key function
fn:current-time()
fn:data()
– Equivalent to
fn:data(.)
fn:data(A)
fn:dateTime(A, A)
fn:day-from-date(A)
fn:day-from-dateTime(A)
fn:days-from-duration(A)
fn:deep-equal(A, A)
fn:deep-equal(A, A, A)
fn:deep-equal(A, A)
fn:deep-equal(A, A, A)
fn:default-collation()
fn:distinct-values(A)
fn:distinct-values(A, A)
fn:doc(A)
fn:doc-available(A)
fn:document(A)
fn:document(A, I)
fn:document-uri()
– Equivalent to
fn:document-uri(.)
fn:document-uri(I)
fn:element-available(A)
fn:element-with-id(x)
– Equivalent to
fn:element-with-id(x, .)
fn:element-with-id(A, N)
fn:empty(I)
fn:encode-for-uri(A)
fn:ends-with(A, A)
fn:ends-with(A, A, A)
fn:environment-variable(A)
fn:error()
fn:error(A)
fn:error(A, A)
fn:error(A, A, N)
fn:escape-html-uri(A)
fn:exactly-one(T)
fn:exists(I)
fn:false()
fn:filter(N, I)
fn:floor(A)
fn:fold-left(N, A, I)
fn:fold-right(N, A, I)
fn:for-each(N, I)
fn:for-each-pair(N, N, I)
fn:format-date(A, A)
fn:format-date(A, A, A, A, A)
fn:format-dateTime(A, A)
fn:format-dateTime(A, A, A, A, A)
fn:format-integer(A, A)
fn:format-integer(A, A, A)
fn:format-number(A, A)
fn:format-number(A, A, A)
fn:format-time(A, A)
fn:format-time(A, A, A, A, A)
fn:function-arity(A)
fn:function-available(A)
fn:function-available(A, A)
fn:function-lookup
– See <IP_ADDRESS> Streamability of
the function-lookup function
fn:function-name(A)
fn:generate-id()
– Equivalent to
fn:generate-id(.)
fn:generate-id(I)
fn:has-children()
– Equivalent to
fn:has-children(.)
fn:has-children(I)
fn:head(T)
fn:hours-from-dateTime(A)
fn:hours-from-duration(A)
fn:hours-from-time(A)
fn:id(x)
– Equivalent to fn:id(x,
.)
fn:id(A, N)
fn:idref(x)
– Equivalent to fn:idref(x,
.)
fn:idref(A, N)
fn:implicit-timezone()
fn:in-scope-prefixes(I)
fn:index-of(A, A)
fn:index-of(A, A, A)
fn:innermost(N)
fn:insert-before(T, A, T)
fn:iri-to-uri(A)
fn:json-to-xml(A)
fn:json-to-xml(A, A)
fn:key(x, x)
– Equivalent to fn:key(x, x,
/)
fn:key(A, A, N)
fn:lang(x)
– Equivalent to fn:lang(x,
.)
fn:lang(A, I)
fn:last
– See <IP_ADDRESS> Streamability of the last
function
fn:local-name()
– Equivalent to
fn:local-name(.)
fn:local-name(I)
fn:local-name-from-QName(A)
fn:lower-case(A)
fn:matches(A, A)
fn:matches(A, A, A)
fn:max(A)
fn:max(A, A)
fn:min(A)
fn:min(A, A)
fn:minutes-from-dateTime(A)
fn:minutes-from-duration(A)
fn:minutes-from-time(A)
fn:month-from-date(A)
fn:month-from-dateTime(A)
fn:months-from-duration(A)
fn:name()
– Equivalent to
fn:name(.)
fn:name(I)
fn:namespace-uri()
– Equivalent to
fn:namespace-uri(.)
fn:namespace-uri(I)
fn:namespace-uri-for-prefix(A, I)
fn:namespace-uri-from-QName(A)
fn:nilled()
– Equivalent to
fn:nilled(.)
fn:nilled(I)
fn:node-name()
– Equivalent to
fn:node-name(.)
fn:node-name(I)
fn:normalize-space()
fn:normalize-space(A)
fn:normalize-unicode(A)
fn:normalize-unicode(A, A)
fn:not(I)
fn:number()
– Equivalent to
fn:number(.)
fn:number(A)
fn:one-or-more(T)
fn:outermost
– See <IP_ADDRESS> Streamability of the
outermost function
fn:parse-xml(A)
fn:parse-xml-fragment(A)
fn:path()
– Equivalent to
fn:path(.)
fn:path(N)
fn:position
– See <IP_ADDRESS> Streamability of the
position function
fn:prefix-from-QName(A)
fn:QName(A, A)
fn:regex-group(A)
fn:remove(T, A)
fn:replace(A, A, A)
fn:replace(A, A, A, A)
fn:resolve-QName(A, I)
fn:resolve-uri(A)
fn:resolve-uri(A, A)
fn:reverse(N)
fn:root
– See <IP_ADDRESS> Streamability of the root
function
fn:round(A)
fn:round(A, A)
fn:round-half-to-even(A)
fn:round-half-to-even(A, A)
fn:seconds-from-dateTime(A)
fn:seconds-from-duration(A)
fn:seconds-from-time(A)
fn:serialize(A)
fn:serialize(A, A)
fn:serialize-json(A)
fn:serialize-json(A, A)
fn:snapshot()
– Equivalent to
fn:snapshot(.)
fn:snapshot(A)
fn:starts-with(A, A)
fn:starts-with(A, A, A)
fn:static-base-uri()
fn:string()
– Equivalent to
fn:string(.)
fn:string(A)
fn:string-join(A)
fn:string-join(A, A)
fn:string-length()
– Equivalent to
fn:string-length(.)
fn:string-length(A)
fn:string-to-codepoints(A)
fn:subsequence(T, A)
fn:subsequence(T, A, A)
fn:substring(A, A)
fn:substring(A, A, A)
fn:substring-after(A, A)
fn:substring-after(A, A, A)
fn:substring-before(A, A)
fn:substring-before(A, A, A)
fn:sum(A)
fn:sum(A, A)
fn:system-property(A)
fn:tail(T)
fn:timezone-from-date(A)
fn:timezone-from-dateTime(A)
fn:timezone-from-time(A)
fn:tokenize(A, A)
fn:tokenize(A, A, A)
fn:trace(A, A)
fn:translate(A, A, A)
fn:true()
fn:type-available(A)
fn:unordered(T)
fn:unparsed-entity-public-id
– See <IP_ADDRESS>
Streamability of the unparsed-entity-public-id function
fn:unparsed-entity-uri
– See <IP_ADDRESS> Streamability
of the unparsed-entity-uri function
fn:unparsed-text(A)
fn:unparsed-text(A, A)
fn:unparsed-text-available(A)
fn:unparsed-text-available(A, A)
fn:unparsed-text-lines(A)
fn:unparsed-text-lines(A, A)
fn:upper-case(A)
fn:uri-collection()
fn:uri-collection(A)
fn:year-from-date(A)
fn:year-from-dateTime(A)
fn:years-from-duration(A)
fn:zero-or-one(T)
map:contains(A, A)
map:entry(A, N)
map:for-each-entry(A, A)
map:get(A, A)
map:keys(A)
map:new()
map:new(A)
map:remove(A, A)
map:size(A)
map:size(A)
math:acos(A)
math:asin(A)
math:atan(A)
math:atan2(A, A)
math:cos(A)
math:exp(A)
math:exp10(A)
math:log(A)
math:log10(A)
math:pi()
math:pow(A, A)
math:sin(A)
math:sqrt(A)
math:tan(A)
accumulator-after
functionSee 18.2.7 Streamability of Accumulators.
To ensure that the supplied value for the first argument (the accumulator name) is not dependent on the streamed input document, its operand usage is classified as navigation.
The posture and sweep of the function call then follow the general streamability rules.
accumulator-before
functionSee 18.2.7 Streamability of Accumulators.
To ensure that the supplied value for the first argument (the accumulator name) is not dependent on the streamed input document, its operand usage is classified as navigation.
The posture and sweep of the function call then follow the general streamability rules.
current
functionThe sweep
of the function is motionless; the posture is the
context posture for evaluation of
the outermost containing XPath expression (that is, the
context posture that would obtain
if the entire XPath expression were replaced with
"."
).
Note:
Although the current
is
supported for streaming, it needs to be used with care. Some common
use cases such as select="$lookup[@name =
current()/name]
will fail, because the streamability rules
require a predicate to be motionless. A workaround is to extract
the relevant value into a variable: select="let $n :=
string(name) return $lookup[@name = $n]
; in turn this
removes the need for the current
function.
The use of current
within a pattern is supported with similar restrictions. In this
case the context posture is always
striding.
current-group
functionXSLT 3.0 introduces the bind-group
attribute on the
xsl:for-each-group
instruction to enable grouping code to be statically analyzed for
streamability. Use of the current-group
and current-grouping-key
functions is therefore incompatible with streaming.
Specifically: a call on the current-group
is roaming and
free-ranging.
current-grouping-key
functionfunction-lookup
functionSee 10.3.5 Dynamic Access to
Functions for special rules that relate to streamability of
calls to the
function-lookup
FO30
function.
With the caveats given there, the function follows the general streamability rules, for a function with two arguments that both have operand usage absorption.
last
functionIf the context posture for a call on the last
FO30
function is striding, crawling, or roaming, then the posture of the
function is roaming, and the sweep is free-ranging.
In all other cases the function is grounded and motionless.
Note:
The cases where last
FO30
can be used without affecting streamability are where the context
item is either grounded or climbing. The latter condition makes
expressions like ancestor::*[@xml:space][last()]
streamable.
There are special rules restricting the use of last
FO30
in the predicate of a pattern: see 19.8.9 Classifying Patterns.
outermost
functionThe single argument to this function has operand usage transmission.
The streamability of the function call follows the general streamability rules with one exception: if the posture of the argument is crawling, then the posture of the result is striding.
Note:
There are cases where the streaming rules allow the construct
outermost(//para)
but do not allow
//para
; the function can therefore be useful in cases
where it is known that para
elements will not be
nested, as well as cases where the application actually wishes to
process all para
elements except those that are nested
within another.
By contrast, the innermost
FO30
function offers no streaming benefits. Although it delivers a
subset of the input nodes as its result, in the correct order, it
is classed as navigational because it needs to look aread in the
input stream before deciding whether a node can be included in the
result.
position
functionThe position
FO30
function follows the general
streamability rules. Since it has no operands, this means it is
grounded and motionless.
Note:
Within an expression, there are no special difficulties in
evaluating the position
FO30
function.
It does have special treatment within a predicate of a pattern, however:
a pattern is not motionless if it contains a call to position
FO30,
as explained in 19.8.9
Classifying Patterns.
root
functionThe zero-argument function root()
is equivalent to
root(.)
.
Given the expression root(X)
, if the item type of
X
is document-node()
, or a subtype
thereof, and if its posture is striding, then root(X)
is
rewritten as X
. Otherwise, it is rewritten as
head((X)/ancestor-or-self::node())
. Streamability
analysis is then applied to the rewritten expression.
Note:
Because path expressions starting with /
are
rewritten to use the root
FO30
function, this ensures that a leading slash is ignored if the
context item is a document node, for example within a template rule
with match="/"
. This improves streamability, because
upwards navigation followed by downward navigation is
disallowed.
unparsed-entity-public-id
functionThe function unparsed-entity-public-id
has an implicit dependency on the context item.
If the context item type is anything other than a document node, the function works without difficulty in streaming mode: in the same way as attributes of ancestor elements are retained and are available while processing descendant elements, the unparsed entities declared in the DTD are retained while processing the body of the document.
While processing the document node itself, however, the contents of the DTD might not yet be available. An arbitrary number of comments and processing instructions are allowed to precede the DTD.
So the rules are:
If the context posture is grounded, the posture is grounded and the sweep is motionless
If the context posture is roaming, the posture is roaming and the sweep is free-ranging
If the context posture is climbing, striding, or crawling, the context item type permits a document node, then the posture is crawling and the sweep is consuming
If the context posture is climbing, striding, or crawling, the context item type does not permit a document node, then the posture is grounded and the sweep is motionless
unparsed-entity-uri
functionThe streamability characteristics of this function are the same
as unparsed-entity-public-id
:
see <IP_ADDRESS>
Streamability of the unparsed-entity-public-id
function.
Note:
Patterns differ from other kinds of construct in that they are not composable in the same way. It is best to think of a pattern as specialized syntax for a function that takes an item as its argument and returns a boolean: true if the pattern matches the item, otherwise false. When we refer to the type of a pattern, however, this refers to the types of item that the pattern is capable of matching, not to the type of value that evaluation of the pattern returns.
The sweep of a pattern is either motionless or free-ranging. (Although there are patterns that could in principle be evaluated by consuming the element node that they match, these are of no interest in the analysis, so they are classified as free-ranging.)
The posture of a pattern is grounded if the pattern is motionless, or roaming otherwise. (This reflects the fact that a pattern always returns a boolean result; it never returns a node in a streamed document.)
Informally, a motionless pattern is one that can be evaluated by a streaming processor when the input stream is positioned at the start of the node being matched, without advancing the input stream.
A pattern is motionless if and only if it satisfies all the following conditions:
The pattern does not contain a RootedPath.
If the pattern contains predicates, then every top-level
Predicate
in the pattern satisfies both the following
conditions:
The expression immediately contained in the predicate is motionless, when assessed with a context posture of striding, and a context item type set to the static type of the expression to which the predicate applies, determined using the rules in 19.2 Determining the Static Type of a Construct.
The predicate is a non-positional predicate.
The use of the term top-level in this rule means that predicates that are nested within other predicates do not themselves have to be non-positional, though they may play a role in the analysis of top-level predicates.
The pattern does not contain (at any depth) a variable reference
bound to a variable declared in the bind-group
attribute of an xsl:for-each-group
instruction.
[Definition: A predicate is a non-positional predicate if it satisfies both of the following conditions:]
The predicate does not contain a function call or named function reference to any of the following functions, unless that call or reference occurs within a nested predicate:
position
FO30
last
FO30
function-lookup
FO30.
Note:
The exception for nested predicates is to avoid disqualifying
patterns such as match="p[@code =
$status[last()]]
.
The expression immediately contained in the predicate is a
non-numeric expression. An expression is non-numeric if its static
item type (see 19.2
Determining the Static Type of a Construct) S
has the property that there is no SequenceType T (other
than xs:error
) such that subtype(T, S) and
(subtype(T, xs:decimal) or subtype(T, xs:double) or subtype(T,
xs:float))
. The subtype
relation is defined in
Section
<IP_ADDRESS> The judgement subtype(A, B)
XP30
Note:
A non-positional predicate can be evaluated by considering each item in the filtered sequence independently; the result never depends on the position of other items in the sequence or the length of the sequence.
A pattern that is not motionless is classified as free-ranging.
The following list shows examples of motionless patterns:
/
*
/*
p
p|q
p/q
p[@status='red']
p[base-uri()]
p[@class or @style]
p[@status]
p[@status = $status-codes[1]]
p[@class | @style]
p[contains(@class, ':')]
p[substring-after(@class, ':')]
p[ancestor::*[@xml:lang]]
text()[starts-with(., '$')]
@price
@price[starts-with(., '$')]
//p/text()[. = 'Introduction']
The following list shows examples of patterns that are not motionless, explaining why not:
id('abc')
(contains a RootedPath
)
$doc//p
(contains a RootedPath
)
p[b]
(the predicate is not motionless)
p[. = 'Introduction']
(the predicate is not
motionless)
p[starts-with(., '$')]
(the predicate is not
motionless)
p[preceding-sibling::p[1] = '']
(the predicate is
not motionless)
p[1]
(contains a positional predicate: return type
is numeric)
p[$pnum + 1]
(contains a positional predicate:
return type is numeric)
p[data(@status)]
(contains a positional predicate:
return type is potentially numeric)
p[position() gt 2]
(contains a positional
predicate: calls position()
)
p[last()]
(contains a positional predicate: calls
last()
)
The examples in this section are intended to illustrate how the streamability rules are applied "top down" to establish whether template rules are guaranteed streamable.
Consider the following template rule, where mode s
is defined with streamable="yes"
:
<xsl:template match="para" mode="s"> <div class="para"> <xsl:apply-templates mode="s"/> </div> </xsl:template>
The processor is required to establish that this template meets the streamability rules. Specifically, as stated in 6.6.3 Streamable Templates, it must satisfy three conditions:
The match pattern must be motionless.
The body of the template rule must be grounded.
The initializers of any template parameters must be motionless.
The third condition is satisfied trivially because there are no parameters.
The first rule depends on the rules for assessing patterns,
which are given in 19.8.9
Classifying Patterns. This pattern is motionless because
(a) it does not contain a RootedPath
, and (b) it
contains no predicates.
So it remains to determine that the body of the template is grounded. The proof of this is as follows:
The sequence constructor forming the body of the template is
assessed according to the rules in 19.8.3 Classifying Sequence
Constructors, which tell us that there is a single operand
(the <div>
literal result
element) which has operand usage U = transmission.
The assessment of the sequence constructor uses the general streamability rules.
These rules require us to determine the type T, sweep
S, posture P, and usage U of each
operand. We have already established that there is a single
operand, with U = transmission. Section
19.2 Determining the Static
Type of a Construct tells us that for all instructions, we
can take T = item()
. The posture P and
sweep
S of the literal result element are established as
follows:
The rules for literal result elements (specifically the
<div>
element) are given in <IP_ADDRESS> Streamability
of Literal Result Elements. This particular literal result
element has only one operand (its contained sequence constructor),
with operand usage U = absorption.
The general streamability rules
again apply. Again the static type T of the operand is
item()
, and we need to determine the posture
P and sweep S.
To determine the posture and sweep of this sequence constructor
(the one that contains the xsl:apply-templates
instruction) we refer again to the general streamability
rules.
The sequence constructor has a single operand (the xsl:apply-templates
instruction); again U = transmission, T =
item()
.
The posture P and sweep S of the xsl:apply-templates
instruction are established as follows:
The rules that apply are in <IP_ADDRESS> Streamability of xsl:apply-templates.
Rule 1 does not apply because the select
expression
(which defaults to child::node()
) is not grounded. This
is a consequence of the rules in <IP_ADDRESS> Streamability of Axis
Steps, specifically:
The context posture of the axis step is established by the template rule as a whole, as striding.
Therefore rules 1 and 2 do not apply.
The statically-inferred context item type is derived from the
match pattern (match="para"
). This gives a type of
element()
. The child axis for element nodes is not
necessarily empty, so rule 3 does not apply.
Rule 4 does not apply because there are no predicates.
So the posture and sweep of the axis step
child::node()
are given by the table in rule 5. The
entry for (context posture = striding, axis = child) gives a
posture of striding and a sweep of consuming.
So the select
expression is not grounded. (The same result
can be reached intuitively: an expression that selects streamed
nodes will never be grounded.)
Rule 2 does not apply because there is no xsl:sort
element.
Rule 3 does not apply because the mode is declared with
streamable="yes"
.
So the posture P and sweep S of the xsl:apply-templates
instruction are established by the general streamability rules,
as follows:
There is a single operand, the implicit
select="child::node()"
expression, with usage
U = absorption.
We have already established that for this operand, the posture P = striding and the sweep S = consuming.
By the rules in 19.2
Determining the Static Type of a Construct, the type
T of the select
expression is
node()
.
In the general streamability rules, the adjusted sweep S' for an operand with (P = striding, U = absorption) is consuming,
Rule 2(d) then applies, so the xsl:apply-templates
instruction is consuming and grounded.
So the sequence constructor that contains the xsl:apply-templates
instruction has one operand with U = transmission, T =
item()
, P = grounded, S =
consuming. Rule 2(d) of the general streamability rules
applies, so the sequence constructor itself has P =
grounded, S = consuming.
So the literal result element has one operand with U
= absorption, T =
item()
, P = grounded, S =
consuming. Rule 2(d) of the general streamability rules
applies, so the literal result element has P = grounded,
S = consuming.
So the sequence constructor containing the literal result
element has one operand with U = transmission,
T = item()
, P = grounded,
S = consuming. Rule 2(d) of the general streamability rules
applies, so this sequence constructor itself has P =
grounded, S = consuming.
So we have established that the sequence constructor forming the body of the template rule is grounded.
Therefore, since the other conditions are also satisfied, the template is guaranteed-streamable.
The analysis presented above could have been simplified by taking into account the fact that the streamability properties of a sequence constructor containing a single instruction are identical to the properties of that instruction. This simplification will be exploited in the next example.
Consider the following template rule, where mode s
is defined with streamable="yes"
:
<xsl:template match="transactions[@currency='USD']" mode="s"> <total><xsl:value-of select="sum(transaction/@value)"/></total> </xsl:template>
Again, as stated in 6.6.3 Streamable Templates, it must satisfy three conditions:
The match pattern must be motionless.
The body of the template rule must be grounded.
The initializers of any template parameters must be motionless.
The third condition is satisfied trivially because there are no parameters.
The first rule depends on the rules for assessing patterns,
which are given in 19.8.9
Classifying Patterns. This pattern is motionless because
(a) it is not a RootedPath
, and (b) every predicate is
motionless and non-positional. The analysis
that proves the predicate is motionless and non-positional proceeds
as follows:
First establish that that the expression
@currency='USD'
is motionless, as follows:
The predicate is a general comparison (GeneralComp
)
which follows the general
streamability rules.
There are two operands: a ForwardsAxisStep
and a
Literal
. Both operand roles are absorption.
The first operand has type T =
attribute()
. Its posture and sweep are determined by the rules in <IP_ADDRESS> Streamability of Axis
Steps. The context posture is striding, so the posture and
sweep are
determined by the entry in the table (rule 5) with context posture
= striding, axis = attribute
: that
is, the result posture is climbing and the sweep is motionless.
The second operand, being a literal, is grounded and motionless.
In the general streamability rules, rule 2(e) applies, so the predicate is grounded and motionless
Now establish that that the expression
@currency='USD'
is non-positional, as follows:
Rule 1 is satisfied: the predicate does not call position
FO30,
last
FO30,
or
function-lookup
FO30.
Rule 2 is satisfied: the expression @currency='USD'
is non-numeric. The static type of the expression is determined
using the rules in 19.2
Determining the Static Type of a Construct as
xs:boolean
, and this has no common subtypes with
xs:decimal
, xs:double
, or
xs:float
.
So both conditions in 19.8.9 Classifying Patterns are satisfied, and the pattern is therefore motionless.
It remains to show that the body of the template rule is grounded. The proof of this is as follows. Unlike the previous example, the analysis is shown in simplified form; in particular the two sequence constructors which each contain a single instruction are ignored, and replaced in the construct tree by their contained instruction.
We need to show that the <total>
literal result element is
grounded.
The rules that apply are in <IP_ADDRESS> Streamability of Literal Result Elements.
These rules refer to the general
streamability rules. There is one operand, the xsl:value-of
child element,
which has operand usage U = absorption,
and type T = item()
.
So we need to determine the posture and sweep of the xsl:value-of
instruction.
The rules are given in <IP_ADDRESS> Streamability of xsl:value-of.
The general streamability rules
apply. There is one operand, the expression
sum(transaction/@value)
, which has operand
usage U = absorption.
The type T of this operand is the return type defined
in the signature of the sum
FO30
function, that is, xs:anyAtomicType
.
The posture P and sweep S are established as follows:
The rules that apply to the call on sum
FO30
are given in 19.8.8
Classifying Calls to Built-In Functions.
The relevant proforma is fn:sum(A)
, indicating that
the general streamability rules
apply, and that there is a single operand with usage U =
absorption.
The type T of the operand
transaction/@value
is determined (by the rules in
19.2 Determining the Static
Type of a Construct) as attribute()
.
The posture P and sweep S of the operand
transaction/@value
are determined by the rules in
<IP_ADDRESS>
Streamability of Path Expressions, as follows:
The expression is expanded to
child::transaction/attribute::value
.
The posture and sweep of the first operand
child::transaction
are determined by the rules in
<IP_ADDRESS> Streamability of
Axis Steps, as follows:
The context posture is striding, because the focus-setting container is the template rule itself.
The context item type is
element()
, based on the match type of the pattern
match="transactions[@currency='USD']"
.
Rules 1 and 2 do not apply because the context posture is striding.
Rule 3 does not apply because the child
axis
applied to an element node is not necessarily empty.
Rule 4 does not apply because there are no predicates.
Rule 5 applies, and the table entry with context posture =
striding, axis = child
gives a
result posture of striding and a sweep of consuming.
The posture of the relative path expression
child::transaction/attribute::value
is therefore the
posture
of its second operand attribute::value
, assessed with
a context posture of striding. This is
determined by the rules in <IP_ADDRESS> Streamability of Axis
Steps, as follows:
The context posture, as we have seen, is striding.
The context item type is
element()
, based on the type of the first operand
child::transaction
.
Rules 1 and 2 do not apply because the context posture is striding.
Rule 3 does not apply because the attribute
axis
applied to an element node is not necessarily empty.
Rule 4 does not apply because there are no predicates.
Rule 5 applies, and the table entry with context posture =
striding, axis = attribute
gives a
result posture of climbing and a sweep of motionless.
The posture of the relative path expression
child::transaction/attribute::value
is therefore
climbing.
The sweep
of the relative path expression
child::transaction/attribute::value
is the wider of
the sweeps of its two operands, namely consuming and motionless.
That is, it is consuming.
So the first and only operand to the call on sum()
has U = absorption, T =
attribute()
, P = climbing, and S =
consuming
Rule 1(b) of the general streamability rules computes the adjusted sweep S'. Rule 1(b)(iii)(A) applies, so the effective operand usage U' is inspection. Rule 1(b)(iii)(A) then computes the adjusted sweep from the table entry for P = climbing, U' = inspection; this shows S' = S, that is, consuming.
Rule 2(d) now applies, so the call on sum()
is
grounded and consuming.
Since the xsl:value-of
instruction has
one operand with U = absorption, T =
xs:anyAtomicType
, P = grounded, and S
= consuming, rule 2(d) again applies, and the
xsl:value-of
instruction is grounded and consuming.
Since the literal result element has one operand with
U = absorption, T =
item()
, P = grounded, and S =
consuming, rule 2(d) again applies, and the
literal result element is grounded and consuming.
Therefore the body of the template rule is grounded, and since the other conditions are also satisfied, it is guaranteed-streamable.
Consider the following code, which is designed to process a transaction file containing transactions in chronological order, and output the total value of the transactions for each day.
<xsl:template name="go"> <out> <xsl:stream href="transactions.xml"> <xsl:for-each-group select="/account/transaction" group-adjacent="xs:date(@timestamp)" bind-group="g" bind-grouping-key="k"> <total date="{$k}" value="{sum($g/@value)}"/> </xsl:for-each-group> </xsl:stream> </out> </xsl:template>
The rules for xsl:stream
say that the
instruction is guaranteed-streamable if the
contained sequence constructor is grounded, and
the task of streamability analysis is to prove that this is the
case. As in the previous example, we will take a short-cut by
making the assumption that a sequence constructor containing a
single instruction can be replaced by that instruction in the
construct tree.
So the task is to show that the xsl:for-each-group
instruction is grounded, which we can do as follows:
The relevant rules are to be found in <IP_ADDRESS> Streamability of xsl:for-each-group.
Rule 1 applies only if the select
expression is
grounded. It is easy to see informally that this
is not the case (an expression that returns streamed nodes is never
grounded). More formally:
The select
expression is a path expression; the
rules in <IP_ADDRESS>
Streamability of Path Expressions apply.
The expression is rewritten as ((root(.) treat as
document-node())/child::account)/child::transaction
The left-hand operand (root(.) treat as
document-node())/child::account
is also a path expression,
so the rules in <IP_ADDRESS> Streamability of
Path Expressions apply recursively:
The left-hand operand root(.) treat as
document-node()
follows the rules for a
TreatExpr
in 19.8.7 Classifying
Expressions; the proforma T treat as TYPE
indicates that the general
streamability rules apply with a single operand having usage
transmission.
This single operand root(.)
follows the rules in
<IP_ADDRESS> Streamability of the
root function. The item type of the operand .
is the context item type, which is the type
established by the xsl:stream
instruction, namely
document-node()
. Under these conditions
root(.)
is rewritten as .
, so the
posture
is the context posture establised by the
xsl:stream
instruction,
namely striding. The sweep is motionless.
The posture and sweep of the expression root(.) treat as
document-node()
are the same as the posture and sweep of root(.)
,
namely striding and motionless
The right-hand operand child::account
is governed
by the rules in <IP_ADDRESS>
Streamability of Axis Steps. The context posture is
striding, and the axis is child
, so
the result posture is striding and the sweep is consuming.
The posture of the path expression is the posture of the right-hand operand, that is striding, and its sweep is the wider sweep of the two operands, that is consuming
Returning to the outer path expression, the posture of the right hand
operand child::transaction
is striding, and its sweep is
consuming.
So the posture of the select
expression as
a whole is the posture of the right hand operand, that is striding; and
its sweep is the wider of the sweeps of the operands, which is
consuming.
Rule 2 does not apply: there is no group-by
attribute.
Rule 3 does not apply: there is a group-adjacent
attribute, but it is motionless. The reasoning is as follows:
The value is a call to the constructor function
xs:date
. The rules in <IP_ADDRESS> Streamability of
Function Calls apply. There is a single operand, whose
required type is atomic, so the operand usage is absorption.
These rules refer to the general
streamability rules, so we need to determine the context item type, posture, and sweep of the operand
expression @timestamp
. This is done as follows:
The expression is an AxisStep
, so the relevant
rules are in <IP_ADDRESS>
Streamability of Axis Steps.
The context posture is the posture of the controlling operand of the focus-setting container, that is,
is the select
expression of the containing xsl:for-each-group
instruction, which as established above is striding. The context item type is similarly the
inferred type of the select
expression, and is
element()
.
Rules 1 and 2 do not apply because the context posture is striding.
Rule 3 does not apply because the attribute axis for an element node is not necessarily empty.
Rule 4 does not apply because there is no predicate.
So the sweep and posture of the expression @timestamp
are given by the table in Rule 5 as climbing and motionless.
Returning to the general
streamability rules for the expression
xs:date(@timestamp)
, the first operand has
U = absorption, T =
attribute()
, P = climbing, S =
motionless.
Under Rule 1(b)(iii)(A), because T =
attribute()
, the operand usage U' becomes
inspection.
Under Rule 1(b)(iii)(A), S' = S = motionless.
Under Rule 2(e), the expression xs:date(@timestamp)
is grounded and motionless.
Rule 4 (under xsl:for-each-group
) does
not apply, because there is no group-starting-with
or
group-ending-with
attribute.
Rule 5 does not apply, because there is no xsl:sort
child.
Rule 6 does not apply, because there is a
bind-group
attribute.
Rule 7 does not apply, because both group-adjacent
and bind-grouping-key
are present.
So Rule 8 applies. This relies on knowing the posture of the sequence
constructor containined in the xsl:for-each-group
instruction: that is, the posture of the total
literal result element. This is
calculated as follows:
The rules that apply are in <IP_ADDRESS> Streamability
of Literal Result Elements. The general streamability rules
apply; there are two operands, the attribute value templates
{$k}
and {sum($g/@value}
, and in each
case the usage is absorption. We can simplify the analysis by
observing that that the empty sequence
constructor contained in the literal result element can be
ignored, since it is grounded and motionless.
Consider first the operand {$k}
.
Section 19.8.6 Classifying Value
Templates applies. This refers to the general streamability rules;
there is a single operand, the expression $k
, with
usage absorption.
The rules for the expression $k
are given in
<IP_ADDRESS>
Streamability of Variable References. These establish that
the expression is grounded and motionless.
It follows that the operand {$k}
expression is also
grounded and motionless.
Now consider the operand {sum($g/@value)}
.
Section 19.8.6 Classifying Value
Templates applies. This refers to the general streamability rules;
there is a single operand, the expression
sum($g/@value)
, with usage absorption.
The rules for the sum
function appear in 19.8.8 Classifying Calls to
Built-In Functions. The proforma is given there as
fn:sum(A)
, which means that the general streamability rules
apply, and that the single operand $g/@value
has usage
absorption. So we need to establish the
posture,
sweep, and
type of this expression, which we can do as follows:
The expression is a RelativePathExpr
, so section
<IP_ADDRESS>
Streamability of Path Expressions applies.
The expression is expanded to
$g/attribute::value
.
The posture and sweep of the left-hand operand $g
are defined in <IP_ADDRESS> Streamability
of Variable References, which has special rules for a
variable bound in the bind-group
attribute of a
containing xsl:for-each-group
instruction. Specifically, the posture of $g
is the posture of the
select
expression, that is striding, and its sweep is the sweep of the
select
expression, that is consuming.
The posture and sweep of the right hand operand
@value
are defined in <IP_ADDRESS> Streamability of Axis
Steps. The context posture is the posture of the left-hand
operand $g
, namely striding; the table in Rule 5 applies,
giving the result climbing and motionless
The posture of the RelativePathExpr
is
the posture of the right hand operand, namely
climbing. The sweep of the RelativePathExpr
is
the wider of the sweeps of its operands, which is consuming
The type of the expression $g/@value
is determined
using the rules in 19.2
Determining the Static Type of a Construct as
attribute()
.
So the sum
function has a single operand with
U = absorption, P = climbing, S =
consuming, T =
attribute()
.
In the general streamability
rules, Rule 1(b)(iii)(A) gives the adjusted usage as
U' = inspection, and Rule 1(b)(iii)(B) gives the
adjusted sweep as S' = S = consuming.
Rule 2(d) gives the posture and sweep of the call to
sum
as grounded and consuming.
So the literal result element has two operands, one of which is grounded and motionless, the other grounded and consuming. Rule 2(d) of the general streamability rules determines that the literal result element is grounded and consuming.
So the content of the xsl:stream
instruction is
grounded, which means that the instruction is
guaranteed-streamable.
Certain constructs allow a stylesheet author to declare that a construct is streamable. Specifically:
Specifying streamable="yes"
on xsl:mode
declares that all
template rules in that mode (and all template rules that
specify mode="#all"
) are streamable;
The xsl:stream
instruction implicitly declares that
its contained sequence constructor is streamable;
Specifying streamable="yes"
on xsl:attribute-set
declares that the attribute set in question is streamable;
Specifying streamable="yes"
on xsl:merge
declares that the
merging process is streamable.
Specifying streamable="yes"
on xsl:accumulator
declares
that the accumulator can be evaluated on a streamed document.
In each case the construct in question is said to be guaranteed-streamable if it satisfies two conditions:
Streamability is declared by specifying
streamable="yes"
.
Streamability analysis following the rules defined in this specification determines that streamed processing is possible (the detailed conditions vary from one construct to another).
[Definition: A guaranteed-streamable construct is a construct that is declared to be streamable and that follows the particular rules for that construct to make streaming possible, as defined by the analysis in this specification.]
For a streaming processor, that is, a processor that claims conformance with the streaming feature:
If a construct is guaranteed-streamable then it must be processed using streaming.
If a construct is declared as streamable but is not guaranteed-streamable (that is, if it fails to satisfy the conditions for streamability defined in this specification), then the processor must be prepared to do any one of the following at user option:
Signal a static error [see ERR XTSE3430]
Process the stylesheet as if it were a non-streaming processor (see below)
Process the stylesheet with streaming if it is able to do so, or signal a static error [see ERR XTSE3430] if it is not able to do so.
[ERR XTSE3430] It is a static error if the stylesheet contains a construct that is declared to be streamable but which is not guaranteed-streamable, unless the user has indicated that the processor is to handle this situation by processing the stylesheet without streaming or by making use of processor extensions to the streamability rules where available.
For a non-streaming processor, the processor must evaluate the construct delivering the same results as if execution used streaming, but with no constraints on the evaluation strategy. (Processing may, of course, fail due to insufficient memory being available, or for other reasons.)
Note:
This specification does not attempt to legislate precisely what constitutes evaluation "using streaming". The most important test is that the amount of memory needed should be for practical purposes independent of the size of the source document, and in particular that the finite size of memory available should not impose a limit on the size of source document that can be processed.
The rules are designed to ensure that streaming processors can analyze streamability using rules different from those in this specification, provided that all constructs that are guaranteed-streamable according to this specification are actually streamable by the implementation. Furthermore, non-streaming processors are not required to analyze streamability at all.
This section describes XSLT-specific additions to the core function library. Some of these additional functions also make use of information specified by declarations in the stylesheet; this section also describes these declarations.
Provides access to XML documents identified by a URI.
document
($uri-sequence
as
item()*
) as
node()*
document ( |
$uri-sequence |
as item()* , |
$base-node |
as node() ) as node()* |
The one-argument form of this function is deterministicFO30, focus-independentFO30, and context-dependentFO30. It depends on static base uri.
The two-argument form of this function is deterministicFO30, focus-independentFO30, and context-independentFO30.
The document
function
allows access to XML documents identified by a URI.
The first argument contains a sequence of URI references. The second argument, if present, is a node whose base URI is used to resolve any relative URI references contained in the first argument.
A sequence of absolute URI references is obtained as follows.
For an item in $uri-sequence
that is an instance of
xs:string
, xs:anyURI
, or
xs:untypedAtomic
, the value is cast to
xs:anyURI
. If the resulting URI reference is an
absolute URI reference then it is used as is. If it is a
relative URI reference, then it is resolved against the base URI of
$base-node
if supplied, or against the base URI from
the static context otherwise (this will usually be the base URI of
the stylesheet module). A relative URI reference is
resolved against a base URI using the rules defined in [RFC3986].
For an item in $uri-sequence
that is a node, the
node is atomized. The result must be a sequence whose items are all instances of
xs:string
, xs:anyURI
, or
xs:untypedAtomic
. Each of these values is cast to
xs:anyURI
, and if the resulting URI reference is an