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 24308 - Overriding templates can also be matching templates, but this case has no rules in the spec
Summary: Overriding templates can also be matching templates, but this case has no rul...
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-01-16 14:09 UTC by Abel Braaksma
Modified: 2014-05-15 14:00 UTC (History)
2 users (show)

See Also:


Attachments

Description Abel Braaksma 2014-01-16 14:09:26 UTC
The only templates that can be overridden are named templates. But if named templates also contain a mode and a match attribute, the behavior is unclear (in fact, I could not find any mention of this case).

Example:

<xsl:override>
    <xsl:template match="P" mode="M" name="N" />
<xsl:override>

This example overrides named template N and thus affects xsl:call-template. However, it (probably) also affects xsl:apply-template. The spec explains[1] that templates bound to a mode can be overridden by template rules in the stylesheet, but it is unclear what happens when the new template rule appears in the xsl:override, let alone what happens when the same node matches the template rule in the xsl:override and in the stylesheet (main package).

While one could argue that the xsl:override takes precedence or that declaration order is taken into consideration, the following example is currently legal but conflicts with the statement "When a template rule specifies mode="#all" this is interpreted as meaning all modes declared implicitly or explicitly within the declaring package of the xsl:template element.":

<xsl:override>
   <xsl:template match="P" mode="#all" name="N" />
</xsl:override>

Perhaps the easiest solution is to disallow mode and match attributes when xsl:template appears within xsl:override. After all, simply specifying template rules on the stylesheet level is already enough to define overrides.


[1] http://www.w3.org/TR/xslt-30/#modes-and-packages
Comment 1 Abel Braaksma 2014-01-16 14:12:50 UTC
Related is also the case of:

<xsl:override>
   <xsl:template name="P" match="N" mode="#unnamed" />
</xsl:override>

or the equivalent without the mode attribute. The conflict here is that you are overriding a template rule, but the unnamed mode is local to a package, hence you are doing something illegal here. Imo, this too is a reason not to allow mode and match attributes here.
Comment 2 Abel Braaksma 2014-01-16 15:36:30 UTC
Apologies, I missed the line "These may appear only as children of the xsl:override element within the xsl:use-package element." under 3.6.3.

However, I leave the bug open, because it leaves the questions on #all and #unnamed (and to some extend, #default). More importantly, since only named templates are allowed, this seems to be too much a restriction. 

In addition, I think we should allow the use of a mode from a used package on the stylesheet level (I don't see why not). When you add a matching template, you are extending or overriding it. Forcing it to be in xsl:override seems counter-intuitive.
Comment 3 Abel Braaksma 2014-01-23 16:24:42 UTC
Please ignore the last paragraph in the previous comment.
Comment 4 Michael Kay 2014-01-29 11:07:06 UTC
Agreed, this is a bit of a mess.

My first reading was that xsl:override was used only for overriding named components (the section heading of 3.6.2.5 is "Overriding named components"). 

But in 3.6.3 we say (table entry "public") "A using package may use xsl:apply-templates to invoke templates in this mode; it may also declare additional template rules in this mode, which are selected in preference to template rules in the used package. These may appear only as children of the xsl:override element within the xsl:use-package element."

It's explicit, I think, that if package P uses package Q, then P can't include template rules that override rules in Q unless (a) the mode is public (which implies it is named) and (b) the overriding rules are children of xsl:override.

I don't think we should allow mode="#all" or mode="#unnamed" within xsl:override; a template rule appearing here must be in a specific public mode declared in the package-being-overridden.
Comment 5 C. M. Sperberg-McQueen 2014-02-10 14:25:59 UTC
The WG discussed this during the ftf meeting in Prague.  The behavior described in comment 4 seems to the WG to be consistent with treating a template with both @name and @match as two templates, which can be overridden together or separately.  The spec should say this.

The mention of 'hidden' as a possible value of the visibility attribute on xsl:expose is incorrect:  it's not allowed on xsl:expose.

The text of section 3.6.3 doesn't say what happens with xsl:apply-imports and xsl:next-match when module boundaries are crossed.  

We should ban mode="#all" and mode="#unnamed" inside xsl:override (the latter is already effectively banned, since the unnamed mode is private).

The sentence about mode="#all" is true (modulo the fact that #all will now be illegal inside override), but is subject to misconstruction owing to its location; we probably need to explain why we are saying this here, or move it to another location.

The note at the end of 3.6.3 should specify select="." on the apply-templates element.

We considered a proposal to simplify the situation by saying that within templates within xsl:override, any call to xsl:apply-imports works with an empty import tree. (The initial import tree is not visible across package boundaries.) 

ACTION:  editor to come back with a proposal on this.
Comment 6 Michael Kay 2014-02-18 20:02:36 UTC
PROPOSAL

1. In the section heading of 3.6.2.5, change "named components" to "components".

2. After the Note in this section, add: "The rules in the remainder of this section apply to components having a <code>name</code> attribute (that is, named components). The only element with no <code>name</code> attribute that can appear as a child of <elcode>xsl:override</code> is an <elcode>xsl:template</code> declaration having a <code>match</code> attribute (that is, a template rule). The rules for overriding of template rules appear in section 3.6.3. If an <elcode>xsl:template</elcode> element has both a <code>name</code> and a <code>match</code> attribute, then it defines both a named component and a template rule, and both sections apply."

3. In 6.6.2, after the description of ERR XTSE0550, add a statement that #all and #unnamed must not be used on an xsl:template that is a child of xsl:override.

4. Move the sentence "When a template rule specifies mode="#all" this is interpreted as meaning all modes declared implicitly or explicitly within the declaring package of the xsl:template element." from 3.6.3 to 6.6.2.

5. In 3.6.3, in the list of allowed values of the visibility attribute, delete "hidden".

6. In 3.6.3, after the sentence "When a template rule specifies mode="#all" this is interpreted as meaning all modes declared implicitly or explicitly within the declaring package of the xsl:template element.", add: "A template rule that is a child of xsl:override must not specify mode="#all".

7. In 6.9, add:

When xsl:apply-imports is used in a template rule that appears within an xsl:override element, the instruction considers as candidates all template rules declared in the used package.

When xsl:next-match is used in a template rules that appears within an xsl:override element, the instruction considers as candidates first, all preceding-sibling template rules, then all template rules declared in the used package.

8. In the Note at the end of 3.6.3, change <xsl:apply-templates/> to <xsl:apply-templates selet="."/>
Comment 7 Abel Braaksma 2014-02-27 17:00:00 UTC
When you intend to copy and paste these into the spec, be aware that the last code snippet contains a typo: selet => select.
Comment 8 Michael Kay 2014-03-06 10:24:49 UTC
Proposal accepted 2014-02-27 with (minuted) changes.

The draft spec has been updated accordingly.