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 5166 - [XSLT 2++] Enhancement: sorting and grouping
Summary: [XSLT 2++] Enhancement: sorting and grouping
Status: CLOSED LATER
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Recommendation
Hardware: PC Windows XP
: P2 enhancement
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
: 4400 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-10-09 05:07 UTC by Michael Kay
Modified: 2014-05-15 14:00 UTC (History)
1 user (show)

See Also:


Attachments

Description Michael Kay 2007-10-09 05:07:05 UTC
Discussions on grouping in XQuery today, and solving some tricky positional grouping problems for a client over the last week, prompt me to capture extensions that could be made to XSLT grouping and sorting capabilities:

(a) allow xsl:variable before xsl:sort, to compute a value that can be used both in the sort key expression and in the subsequent processing of the relevant item:

<xsl:for-each select="product">
  <xsl:variable name="profitability" select="price - cost"/>
  <xsl:sort select="$profitability"/>
  <xsl:value-of select="$profitability"/>
</xsl:for-each>

(b) allow grouping keys to be specified in a separate group element:

<xsl:for-each-group select="product">
  <xsl:group-by select="price"/>
  <xsl:value-of select="avg(current-group()/cost)"/>
</xsl:for-each-group>

(c) use this to allow composite grouping keys

<xsl:for-each-group select="product">
  <xsl:group-by select="category"/>
  <xsl:group-by select="colour"/>
  <xsl:value-of select="avg(current-group()/cost)"/>
</xsl:for-each-group>

(d) allow control over how a sequence-valued group key is handled

<xsl:group-by select="author" compare="each | first | only | sequence | set"/>

(each assigns to one group for each value of the key; first ignores all but the first, only requires exactly one, sequence compares the sequences as sequences, set compares them as sets)

(e) allow variables to be declared before the group-by:

<xsl:for-each-group select="product">
  <xsl:variable name="profitability" select="(price - cost) div cost"/>
  <xsl:variable name="profit-band" select="$profitability idiv 0.2"/>
  <xsl:group-by select="$profit-band"/>
  <xsl:value-of select="format-number($profit-band)"/>
</xsl:for-each-group>

or

<xsl:for-each-group select="*">
  <xsl:variable name="is-bullet" select="boolean(self::bullet)"/>
  <xsl:group-adjacent select="$is-bullet"/>
  <xsl:choose>
    <xsl:when test="$is-bullet">
       ...
</xsl:for-each-group>

(e) group-starting-when in place of group-starting-with; the value is an expression rather than a pattern, and a new group starts when the expression is true. Allows the same concepts as above to be used for this case (and group-ending-when).

<xsl:for-each-group select="para">
  <xsl:variable name="is-top-level" select="@level = 0"/>
  <xsl:variable name="is-heading" select="title and not preceding-sibling::*[1]/self::title"/>
  <xsl:group-starting-when test="$is-top-level and $is-heading"/>
  <xsl:if test="$is-heading">
Comment 1 Michael Kay 2007-10-10 17:32:44 UTC
See also bug #4400
Comment 2 Sharon Adler 2007-10-10 19:32:10 UTC
Considered as an enhancement request for VNext
Comment 3 Michael Kay 2008-09-05 13:42:12 UTC
*** Bug 4400 has been marked as a duplicate of this bug. ***
Comment 4 Michael Kay 2009-04-14 10:13:44 UTC
See also bug #4921

Use case encountered today: an up-conversion from a text file - needed to use group-starting-with on the sequence of text lines obtained effectively from the unparsed-text-lines() function. Had to convert these strings to nodes because group-starting-with only works on a sequence of nodes!

Possible solutions:

(a) group-starting-when as suggested above (accepting an expression rather than a pattern)

(b) patterns that match atomic values - this would also allow generalizing apply-templates to work on atomic values. For example, allow the pattern ".[predicate]" to match an atomic value for which the predicate is true. That's a bit inelegant for the case of ".[. instance of xs:string]" - perhaps allow "~xs:string" or type(xs:string) for that case.
Comment 5 Michael Kay 2010-07-16 14:48:24 UTC
Concerning (a), we can see the justification for this capability but are concerned about how the semantics would be specified. Would it require introducing the concept of tuple streams? Need to revisit.

Concerning (b)-(d) we have looked at composite grouping keys under bug #5577

For (e) the concerns about semantics are the same as (a) only more so.

For the second (e), positional grouping enhancements are considered under bug #4921.
Comment 6 Michael Kay 2011-06-08 20:28:31 UTC
Resolved at the Prague F2F March 2011 to mark this as "Later".