- From: <bugzilla@wiggum.w3.org>
- Date: Tue, 09 Oct 2007 05:07:05 +0000
- To: public-qt-comments@w3.org
- CC:
http://www.w3.org/Bugs/Public/show_bug.cgi?id=5166
Summary: [XSLT 2++] Enhancement: sorting and grouping
Product: XPath / XQuery / XSLT
Version: Recommendation
Platform: PC
OS/Version: Windows XP
Status: NEW
Severity: enhancement
Priority: P2
Component: XSLT 2.0
AssignedTo: mike@saxonica.com
ReportedBy: mike@saxonica.com
QAContact: public-qt-comments@w3.org
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">
Received on Tuesday, 9 October 2007 05:07:14 UTC