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 28775 - [XSLT30] Suggestion: prioritise templates with named modes over templates with mode="#all"
Summary: [XSLT30] Suggestion: prioritise templates with named modes over templates wit...
Status: CLOSED WONTFIX
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Working drafts
Hardware: PC All
: 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: 2015-06-06 17:15 UTC by Tom Hillman
Modified: 2015-06-13 09:58 UTC (History)
0 users

See Also:


Attachments

Description Tom Hillman 2015-06-06 17:15:15 UTC
Consider the following in XSLT 2:

<xsl:template match="node()|@*" mode="#all">
  <xsl:apply-templates select="node()|@*" mode="#current"/>
</xsl:template>

<xsl:template match="element" mode="someMode">
  -Some operation-
</xsl:template>

<xsl:template match="text()[contains(., 'x')] mode="anotherMode" priority="-0.4">
 -Another operation-
</xsl:template>

The only way to avoid a conflict between the first and third templates is to assign the third with an explicit priority.  This is a niggle, and may become a risk where stylesheets have multiple authors (or long periods between edits)

This is un-necessary with the second template because the named element always has a higher precedence than the generic 'node()'.

My suggestion is that, in a similar way, named modes should always have a higher precedence than the generic '#all' mode for XSLT 3

You could point out that the 'better' way of approaching the problem is with the use of template rules on mode elements; this is true, but I think this is still a valid bug because
1. as reported in bug 28774 this exact behaviour is not replicated by shallow-skip
2. If XSLT 3 is also implementing #all, the same limitations will apply.

I believe such a change would be backwards compatible.
Comment 1 Michael Kay 2015-06-07 08:34:39 UTC
Personal response (and/or request for clarification):

In your example, 

match="text()[contains(., 'x')]"

(with no priority attribute)

would have higher priority than

match="node()|@*"

Even without the predicate a text node would match match="text()" in preference to match="node()".

So I'm not sure the example justifies the proposal.

I can see the logic that mode="#all" is intuitively some kind of fallback and should therefore rank lower, but it's not clear how this would fit into the priority/precedence rules, and it's not clear that it could be made backwards compatible. Even if we only took the mode attribute into account when the two rules have the same precedence/priority, XSLT 2.0 processors are entitled to resolve the ambiguity by choosing the rule that comes last, and a stylesheet that relied on this behaviour would need to be changed.
Comment 2 Tom Hillman 2015-06-07 09:42:59 UTC
This teaches me for writing examples without testing them!

Here's a better example:

Input document:

<text>Only the text such as <element><b>Hello</b> World!</element> will be output</text>

Stylesheet:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">

  <xsl:output method="text"/>

  <xsl:template match="text()" mode="text">
    <xsl:value-of select="."/>
  </xsl:template>

  <xsl:template match="node() | @*" mode="#all">
    <xsl:apply-templates select="node() | @*" mode="#current"/>
  </xsl:template>

  <xsl:template match="element">
    <xsl:apply-templates select="node() | @*" mode="text"/>
  </xsl:template>

</xsl:stylesheet>

Desired output:
Hello World!

In it's current format, the stylesheet doesn't work (Saxon throws a couple of ambiguous match warnings).  The stylesheet does work if you specify the priority on the first template.

You can also resolve the behaviour by moving the match template to the end of the stylesheet, but this seems unreliable to me and still leaves the warnings.

It is a shame that the behaviour isn't backwards compatible, and I would understand if that precludes any change; I still think that for the future it's better to have a defined behaviour than relying on implementation choices.
Comment 3 Michael Kay 2015-06-12 08:30:56 UTC
Response on behalf of the Working Group:

Many thanks for reviewing the specification and making this suggestion.

While WG members agreed that this change would be beneficial for the use cases described, there were two concerns:

(a) there is a balance to be found between making the implicit priority rules more intelligent, and keeping them memorable. There are limits to our ability to "do the right thing" in all cases for users who don't use any user-defined priority attributes and rely on the system to take care of it. On the whole, we would encourage people with complex sets of template rules to be aware of priorities and set them manually where necessary (or even where not necessary).

(b) any change to the default priority rules for constructs that were legal in XSLT 2.0 will break existing code, and we don't make breaking changes unless there are very strong justifications indeed; the case here is not strong enough.

We hope you will accept this decision by marking the bug as closed, but if you want to reopen the discussion with new information you are welcome to do so.
Comment 4 Tom Hillman 2015-06-13 09:58:21 UTC
Thanks; I accept the committee's reasoning, and any reluctance I would have in closing this is mitigated with the acceptance of attribute behaviour for bug 28774.