This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 27189 - [XSLT30] xsl:copy on-empty and document nodes ambiguities
Summary: [XSLT30] xsl:copy on-empty and document nodes ambiguities
Status: CLOSED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Last Call drafts
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-29 12:28 UTC by Abel Braaksma
Modified: 2015-10-29 09:50 UTC (History)
0 users

See Also:


Attachments

Description Abel Braaksma 2014-10-29 12:28:32 UTC
The spec says two things in 11.9.1.1:

(1) "If the selected item is not an element node, the attribute has no effect, except that static errors must be reported and type errors may be reported."

(2) "If the result of the instruction in the absence of the on-empty attribute would be an element or document node ...."

While I think it is possible to create a document node inside xsl:copy, it would be a document-node as a child of a copied element node, which would be ignored and it won't change the item type.

There are two ways to solve this ambiguity:
1) remove the reference to document nodes in quote (2)
2) allow document node creation and allow the on-empty type to be document-node

The second solution has the preference (see mail 0057.html below), but if we allow that, we also need to make sure that the type of on-empty is the same as the type of the selected item.

This bug is created as a result of WG email discussion, see 
- https://lists.w3.org/Archives/Member/w3c-xsl-wg/2014Oct/0056.html (member only)
- https://lists.w3.org/Archives/Member/w3c-xsl-wg/2014Oct/0057.html (member only)
Comment 1 Abel Braaksma 2014-10-31 22:28:14 UTC
As a self-reminder, after this bug is resolved, review rev #765 in the XT3 repository, 2014-10-29 (commit comment refers to this bug number and bug 24049).
Comment 2 Abel Braaksma 2014-11-05 21:06:47 UTC
We should also consider the following scenario, when solving this:

<xsl:copy select="(document-node(root) | somechild)[1]"
    on-empty="my:create-element()">
    <xsl:apply-templates />
</xsl:copy>


This instruction creates either an empty element or empty document. If it creates an empty document, the on-empty creates the wrong type to replace this. Should we, in this case, allow the implicit creation of the document node?

Also, semantically, @on-empty is very vague: many of my attempts assumed that it fires when the selection is empty, but in fact, it fires when the resulting sequence constructor returns emptiness. 

I believe we should make this very, very clear, or rename to something like "on-empty-content", or even (rigorous, I know), an instruction <xsl:on-empty select="'foo'">...</xsl:on-empty>, which would be more universally applicable and less complex in rules. More importantly, it is semantically clearer (at least imho) and does not suffer from the type-safety rules.
Comment 3 Michael Kay 2014-12-18 21:27:08 UTC
The WG agreed to make changes as defined in message

https://lists.w3.org/Archives/Member/w3c-xsl-wg/2014Nov/0027.html
(member-only link)

The effect of the changes is, in summary:

(1) Drop the existing on-empty attribute from the instructions on which it appears

(2) Introduce a new instruction xsl:on-empty which is evaluated only if the result of the containing sequence constructor would otherwise be an empty sequence

(3) Introduce a new instruction xsl:on-non-empty which is evaluated only if the result of the containing sequence constructor would otherwise be a non-empty sequence

(4) Introduce a new instruction xsl:conditional-content whose effect is to filter the results of evaluating its contained sequence constructor, by removing any items with "empty content". For document and element nodes this is defined to mean "no child nodes", for other items it is defined to mean string(.) = "".