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 28931 - [xslt 3.0] apply-templates across packages
Summary: [xslt 3.0] apply-templates across packages
Status: CLOSED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Last Call 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-07-09 12:19 UTC by Michael Kay
Modified: 2015-10-29 12:42 UTC (History)
1 user (show)

See Also:


Attachments
Proposed rewrite of section 3.5.3.1 (57.64 KB, application/pdf)
2015-08-03 10:16 UTC, Michael Kay
Details

Description Michael Kay 2015-07-09 12:19:54 UTC
I've written a test case override-v-004 and I'm having difficulty establishing from the spec what the correct result is. To precis the problem, there is a package A which has

<xsl:use-package B
 <xsl:override
  <xsl:variable name="V" select="13"/>

<call-template name="go"/>

And there is a package B which has

<xsl:variable name="V select="1"/>

<xsl:template match="*[$V=1]">one</xsl:template>
<xsl:template match="*[$V=13]">thirteen</xsl:template>

<xsl:template name="go" visibility="public">
  <xsl:apply-templates select="/*"/>
</xsl:template>

Which template rule should fire? Intuitively, the one with $V=13. Certainly, any reference to $V within named components of B invoked via something in A would evaluate to 13.

Let's first assume that we treat the apply-templates and xsl:template declarations as if they had an explicit mode="U".

Notation: C(P) means the version of component C that appears explicitly or implicitly in package P.

Then the call-template instruction is a call to go(A), and the apply-templates instruction in go(A) is bound to mode U(A) which is a copy of mode U(B) but with different component bindings.

I think there are two clarifications needed to the spec to make this work unambiguously.

(a) we need to make it clear that when xsl:apply-templates defaults the mode attribute, this behaves as if it were a component reference to a named mode.

(b) In 3.5.3.5 where we say "When reference resolution is performed for a component C, each symbolic reference R that is present in the declaration of C is processed as follows:", we need to make it clear that for template rules, performing reference resolution for a mode means resolving references for all template rules in that mode, and that the "symbolic references that are present in the declaration of the mode" are all the symbolic references in any of those template rules".

I think there may be additional problems when a mode itself is overridden, but we'll put that problem on one side for now.
Comment 1 Michael Kay 2015-08-03 10:16:27 UTC
Created attachment 1621 [details]
Proposed rewrite of section 3.5.3.1
Comment 2 Michael Kay 2015-08-03 10:19:14 UTC
In preparing a resolution to this bug, I found that there were problems with the text of 3.5.3.1 on resolving symbolic references. Section 3.5.3 has a paragraph starting 

For example, suppose that in some package P, function A calls B, which in turn calls C, and that B is private. Now suppose that in some package Q which uses P, C is overridden. 

that correctly explains what happens when a private component refers to a public component, and the public component is overridden. But 3.5.3.1 does not reflect this logic; it suggests wrongly that references from a private component are fixed and immutable. I have therefore posted a proposed rewrite of section 3.5.3.1.
Comment 3 Michael Kay 2015-08-03 10:29:53 UTC
In addition to the rewrite of 3.5.3.1, the following changes are proposed to resolve this bug:

In 3.5.3, in the paragraph "Every component has a declaration in some stylesheet module and therefore within some package. In the case of attribute sets, there may be several declarations….” change the second sentence to start “In the case of attribute sets and keys…” [separate problem fixed en passent; changed to align with the next para].

In the paragraph "Template rules are not components in their own right; unlike named templates, they are never referenced by name. Component references within a template rule (for example, references to functions, global variables, or named templates) are treated as occurring within the component that represents the containing mode.”, after the second sentence, add “This includes component references within the match patterns of template rules”.

After this paragraph, add “An xsl:apply-templates instruction with no mode attribute is treated as a component reference to the unnamed mode. Note that there is an unnamed mode in every package, and an unnamed mode always has private visibility.” Also add: “Where a template has a name and also a match pattern, it is treated as if there were two separate templates, one with a name and one with a match pattern.”

At the end of 3.5.3.4, add “Modes are not overridable, so a mode can never be referred to by the name xsl:original."

In 3.5.3.5, before the paragraph "When a package P is used by another package Q…”, add “Note. This includes the case where the component reference is the reference from an xsl:apply-templates instruction to a named or unnamed mode. 

In 3.5.4, the second paragraph reads: "The unnamed mode is local to a package: in effect, each package has its own private unnamed mode, and the unnamed mode of one package does not interact with the unnamed mode of any other package.”. Add: “An xsl:apply-templates instruction with no mode attribute is treated as a reference to the unnamed mode.” Then add an example similar to the example in the bug 28931 illustrating the implications of this.
Comment 4 Abel Braaksma 2015-08-17 09:14:00 UTC
The WG discussed this bug at the telcon of 13 August 2015 and decided:

DECISION: the XSLWG accepts the proposals in comment#1 and comment#3 of the bug report, taking the observations here (on xsl:original and built-in template rules) into account

The observations, in summary, were:

- the PDF in comment#1 does not mention binding of hidden components to xsl:original or #xsl:original, these bindings should be added.

- in a mail discussion (reference unknown) Abel made the observation that it is unclear what happens with built-in template rules: when you override a mode by adding a template rule to xsl:override, and we say that all template rules in the current package has higher precedence than in any used package, how does that relate to the built-in template rules? Answer: these should *not* be triggered before any existing template rule in any (used or using) package has been processed.

Example (not from the minutes):

Package A:
<xsl:mode name="M" on-no-match="shallow-copy" />

<xsl:template mode="M" match="foo">
   <xsl:value-of select="." />
</xsl:template>

Package B:
<xsl:use-package name="A">
   <xsl:override>
       <xsl:template match="bar" mode="M">
           <xsl:copy>
              <xsl:apply-templates select="foo" />
           </xsl:copy>
       </xsl:template>
    </xsl:override>
</xsl:use-package>

Now: in Package B there exist, by default, the built-in template rules for any mode that has come into existence (here mode M). Because any template rule in B has higher priority than any template rule in A, this suggests that match="foo" can never be hit.

One way to tackle this is, perhaps, to stipulate that any built-in template rule only exists inside the defining package (where the xsl:mode declaration is). That way, no built-in template rules exist inside B and the inheritance priority issue does not rise.
Comment 5 Abel Braaksma 2015-08-17 09:14:47 UTC
> <xsl:apply-templates select="foo" />

correction, this should have been <xsl:apply-templates select="foo" mode="M" />