[Bug 29455] [xslt30ts] on-empty-113a

https://www.w3.org/Bugs/Public/show_bug.cgi?id=29455

--- Comment #5 from Michael Kay <mike@saxonica.com> ---
I have spent some time thinking about this. I think that incorporating rules
about separators between atomic values into xsl:on-empty and xsl:on-non-empty
makes things excessively complicated, it makes a difference only in extreme
edge cases, and it is unnecessary. I think we can achieve very close alignment
with the rules for complex content construction (CCC) with the following
changes.

PROPOSAL:

A. In 8.4.2, xsl:on-empty, replace

An xsl:on-empty instruction is evaluated only if every preceding sibling
instruction, text node, and literal result element in the same sequence
constructor returns either an empty sequence, or a sequence consisting entirely
of zero-length text nodes and/or document nodes with no children.

by

[Definition: an item is *insignificant* if it is one of the following: a
zero-length text node; a document node with no children; an atomic value which,
on casting to xs:string, produces a zero-length string; or an array which on
flattening (using the array:flatten function) produces either an empty sequence
or a sequence consisting entirely of insignificant items.]

[Definition: an item is *significant* if it is not *insignificant*].

An xsl:on-empty instruction is triggered only if every preceding sibling
instruction, text node, and literal result element in the same sequence
constructor returns either an empty sequence, or a sequence consisting entirely
of *insignificant* items.

If an xsl:on-empty instruction is triggered, then the result of the containing
sequence constructor is the result of the xsl:on-empty instruction.

<Note>This means that the (insignificant) results produced by other
instructions in the sequence constructor are discarded. This is relevant mainly
when the result of the sequence constructor is used for something other than
constructing a node: for example if it forms the result of a function, or the
value of a variable, and the function or variable specifies a required type.

When streaming, it may be necessary to buffer insignificant items in the result
sequence until it is known whether the result will contain items that are not
insignificant. In many common situations, however - in particular, when the
sequence constructor is being used to create the content of a node -
insignificant items can be discarded immediately because they do not affect the
content of the node being constructed.
</Note>

<Note>In nearly all cases, the rules for xsl:on-empty are aligned with the
rules for constructing complex content. If the sequence constructor within a
literal result element or an xsl:element instruction includes an xsl:on-empty
instruction, then the content of the element will be the value delivered by the
xsl:on-empty instruction if and only if the content would otherwise be empty.
There is one minor exception to this rule: if the sequence constructor delivers
multiple zero-length strings, then in the absence of the xsl:on-empty
instruction the element would contain whitespace, made up of the separators
between these zero-length strings; but xsl:on-empty takes no account of these
separators.</Note>

<Note>Attribute and namespace nodes created by the sequence constructor are
significant; the xsl:on-empty instruction will not be triggered if such nodes
are present. If this is not the desired effect, it is possible to partition the
sequence constructor to change the scope of xsl:on-empty, for example

<ol>
  <xsl:attribute name="class" select="numbered-list"/>
  <xsl:sequence>
     <xsl:value-of select="xyz"/>
     <xsl:on-empty select="'The list is empty'"/>
  </xsl:sequence>
</ol>

</Note>

B. In 8.4.3, xsl:on-non-empty, change:

An xsl:on-non-empty instruction is evaluated only if there is at least one
sibling node in the same sequence constructor, excluding xsl:on-empty and
xsl:on-non-empty instructions, whose evaluation yields a sequence containing an
item other than a zero-length text node or a document node with no children. If
this condition applies, then all xsl:on-non-empty instructions in the
containing sequence constructor are evaluated, and their results are included
in the result of the containing sequence constructor in their proper positions.

to:

An xsl:on-non-empty instruction is evaluated only if there is at least one
sibling node in the same sequence constructor, excluding xsl:on-empty and
xsl:on-non-empty instructions, whose evaluation yields a sequence containing an
item that is *significant*. If this condition applies, then all
xsl:on-non-empty instructions in the containing sequence constructor are
evaluated, and their results are included in the result of the containing
sequence constructor in their proper positions.

<Note>
xsl:on-non-empty is typically used to generate headers or footers appearing
before or after a list of items, where the header or footer is to be omitted
when there are no items in the list.
</Note>

C. In 8.4.4, change clause 4(b) from

Otherwise, the instruction is evaluated and its results are appended to R.

to

Otherwise, the existing contents of R are discarded, the instruction is
evaluated, and its results are appended to R. 

<note>The need to discard items from R arises only when all the items in R are
insignificant. Streaming implementations may therefore need a limited amount of
buffering to retain insignificant items until it is known whether they will be
needed. However, in many common cases an optimized implementation will be able
to discard insignificant items such as empty text nodes immediately, because
when a node is being constructed using the rules in CCC or CSC, such items have
no effect on the final outcome.</note>

D. The above rules align the treatment of arrays between xsl:on-empty,
xsl:on-non-empty, CCC, and CSC: for example in each case [[],[]] is treated the
same as []. It seems desirable also to bring the rules for xsl:where-populated
into line. Therefore, in section 8.4.1, change

o An array (see 27.7.1 Arrays) with no members.

to

o An array (see 27.7.1 Arrays) where the result of flattening the array using
the array:flatten function is either an empty sequence, or a sequence in which
every item is deemed empty (applying these rules recursively).

-- 
You are receiving this mail because:
You are the QA Contact for the bug.

Received on Thursday, 18 February 2016 09:10:23 UTC