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 28774 - [XSLT30] Suggestion: allow shallow skip to match on non element nodes
Summary: [XSLT30] Suggestion: allow shallow skip to match on non element nodes
Status: CLOSED FIXED
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 15:50 UTC by Tom Hillman
Modified: 2015-06-13 09:56 UTC (History)
0 users

See Also:


Attachments

Description Tom Hillman 2015-06-06 15:50:14 UTC
The current implementation of shallow copy will mean that you cannot write a template matching on e.g. an attribute or predicated text() node in that mode: you have to write such a template with existing knowledge about the context it will exist in.

I would suggest that more desirable behaviour would be to apply templates on @* and node() (cf. shallow copy), with the default behaviour on matching of those items being to output an empty sequence (cf. existing behaviour for element nodes).

I believe this is a different bug to bug 22379, which seems to be more about documentation than behaviour.

BACKGROUND: Michael Kay suggested to me that the built in template rules would be an alternative to existing niggles with XSLT 2 behaviour around using mode="#all" template matching, however the current shallow copy behaviour means that the same functionality without using #all is impossible. (matching on non element nodes requires explicit priority values to be set - perhaps that should be a separate bug since #all is still in the spec!)
Comment 1 Tom Hillman 2015-06-06 17:13:37 UTC
Oops, I mean shallow skip, not shallow copy!

Apologies -T
Comment 2 Michael Kay 2015-06-07 08:59:42 UTC
(Personal response)

I don't think I understand either the problem or the proposed solution.

Suppose you want to output all the section headings in the document. You can achieve this with

<xsl:mode on-no-match="shallow-skip"/>

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

Can you give a concrete example of a transformation where the definition of shallow-skip gives you problems?
Comment 3 Tom Hillman 2015-06-07 09:30:07 UTC
Hi,

In your counter-example, you would need to know that the text() nodes' context (section/heading/text()) - if I were interested in such a transform I would probably match on the heading element, which is why it's easy to miss this behaviour

The problem is when you wish to define some over-riding behaviour for text() in general (or some other non-element node); Consider the following mode which might deliver a list of @id and @doi values as elements:

<xsl:mode name="IDs" on-no-match="shallow-skip"/>

<xsl:template match="@id"><ID><xsl:value-of select="."/></ID></xsl:template>
<xsl:template match="@doi"><ID class="doi"><xsl:value-of select="."/></ID></xsl:template>

If I understand the behaviour correctly, the templates won't match anything
Comment 4 Michael Kay 2015-06-07 19:49:34 UTC
The built-in template for element nodes does apply-templates to child nodes, so I don't see a problem with processing text nodes: if there is a template rule that matches text nodes then it will fire. 

It's true that it doesn't apply-templates to attribute nodes, so your example using attribute rules wouldn't work. That's something we could consider changing: that is, make the default template for element nodes apply templates to attributes as well as children. That would align it with shallow-copy. It would depart from the default rule for text-only-copy, which we cannot change for compatibility reasons.
Comment 5 Tom Hillman 2015-06-08 07:26:36 UTC
How about processing instructions and comments?

My assumption that only elements (and the document node) were being matched comes from the following equivalent template in the spec at http://www.w3.org/TR/xslt-30/#built-in-templates-shallow-skip

<xsl:template match="document-node()|element()" mode="M">
  <xsl:apply-templates mode="#current"/>
</xsl:template>

Should there be a select statement on the apply-templates for clarity?
Comment 6 Michael Kay 2015-06-08 07:37:19 UTC
The shallow-skip section gives two template rules:

<xsl:template match="document-node()|element()" mode="M">
  <xsl:apply-templates mode="#current"/>
</xsl:template>

<xsl:template match="." mode="M"/>

I would have assumed that most readers know that <xsl:apply-templates/> means <xsl:apply-templates select="child::node()"/>, but if people feel that the latter would add clarity, I'm happy to oblige.

Perhaps readers are less familiar with the fact that match="." matches anything (including text nodes, processing instruction and comment nodes, attribute nodes, atomic values etc). But we do attempt to explain it in the prose.
Comment 7 Michael Kay 2015-06-12 08:48:19 UTC
Response on behalf of the Working Group:

The working group felt that there was no problem with the way that shallow-skip handles text (and comment/PI) nodes: the built-in template for element nodes applies-templates to its children, and the built-in template for text nodes does nothing; so if you want to process all the text nodes, you can simply define a rule to process those text nodes.

However the WG accepted that there is a usability problem with attribute nodes, and resolved to fix this by changing the built in template rule for document and element nodes to do the following:

<xsl:template match="." mode="M">
    <xsl:apply-templates select="@*" mode="M"/>
    <xsl:apply-templates select="node()" mode="M"/>
</xsl:template>

which is aligned with the behaviour of shallow-copy.

The effect is that if you want to process attribute nodes, you simply add template rules that match the attribute nodes to be processed. In the absence of such rules, the behaviour is unchanged, since the default rule for attribute nodes is to do nothing.

Many thanks for raising the issue. We would be grateful if you would indicate your acceptance of the response by marking it closed, but if you want to re-open the issue with new information you are welcome to do so.
Comment 8 Tom Hillman 2015-06-13 09:56:39 UTC
Excellent - Many thanks!