Re: [xsl] grouping

Subject: Re: [xsl] grouping
From: "G. Ken Holman g.ken.holman@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 2 Jan 2026 15:23:23 -0000
Ouch! I think I prefer David's answer, but this is what I came up with working
semantically instead of syntactically:

~/t $ cat dave.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:xs="http://www.w3.org/2001/XMLSchema";
  xmlns:math="http://www.w3.org/2005/xpath-functions/math";
  xmlns:dave="urn:X-Dave"
  exclude-result-prefixes="xs math dave"
  version="3.0">

<xsl:output method="text"/>

<xsl:template match="data">
  <xsl:for-each-group select="period"
                      group-by="dave:modulo3hours(start)">
    <xsl:value-of select="'&#xa;' || current-grouping-key() || ' ' ||
                      count(current-group()) || ' entries with total cost: '
||
                      sum(current-group()/number(cost))"/>
  </xsl:for-each-group>
  <xsl:text>&#xa;</xsl:text>
</xsl:template>

<xsl:function name="dave:modulo3hours" as="xs:string">
  <xsl:param name="start" as="element(start)"/>
  <xsl:variable name="startTime" select="xs:time($start/time || ':00')"/>
  <xsl:variable name="fromMidnightDuration"
                select="xs:duration($startTime - xs:time('00:00:00') )"/>
  <xsl:variable name="fromMidnightMinutes"
                select="hours-from-duration($fromMidnightDuration) * 60 +
                        minutes-from-duration($fromMidnightDuration)"/>
  <xsl:sequence select="$start/date || '-' || $fromMidnightMinutes idiv
180"/>
</xsl:function>

</xsl:stylesheet>
~/t $ xslt2 dave.xml dave.xsl

12-01-0 3 entries with total cost: 3.32516625
12-01-1 6 entries with total cost: 11.899479375
12-01-2 6 entries with total cost: 122.236542015
12-01-3 6 entries with total cost: 66.41845759499999
12-01-4 6 entries with total cost: 48.98321693999999
12-01-5 6 entries with total cost: 113.2815999
12-01-6 6 entries with total cost: 28.573543214999997
12-01-7 6 entries with total cost: 25.968715394999997
12-02-0 1 entries with total cost: 0.6300315
~/t $


At 02/01/2026 15:08 +0000, Dave Pawson dave.pawson@xxxxxxxxx wrote:
>Thank you David.\xC2
>
>regards
>
>On Fri, 2 Jan 2026 at 15:04, David Carlisle
<mailto:d.p.carlisle@xxxxxxxxx>d.p.carlisle@xxxxxxxxx
<<mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>xsl-list-service@xxxxxxxxxxx
rrytech.com> wrote:
>this?
>
><!DOCTYPE HTML>
><html>
>\xC2  \xC2 <p>12-01:0 3.32516625</p>
>\xC2  \xC2 <p>12-01:3 11.899479375</p>
>\xC2  \xC2 <p>12-01:6 122.236542015</p>
>\xC2  \xC2 <p>12-01:9 66.41845759499999</p>
>\xC2  \xC2 <p>12-01:12 48.98321693999999</p>
>\xC2  \xC2 <p>12-01:15 113.2815999</p>
>\xC2  \xC2 <p>12-01:18 28.573543214999997</p>
>\xC2  \xC2 <p>12-01:21 25.968715394999997</p>
>\xC2  \xC2 <p>12-02:0 0.6300315</p>
></html>
>
>
>from
>
><xsl:stylesheet version="2.0"
>xmlns:xsl="<http://www.w3.org/1999/XSL/Transform>http://www.w3.org/1999/XSL/
Transform"
>xmlns:xs="<http://www.w3.org/2001/XMLSchema>http://www.w3.org/2001/XMLSchema
"
>xmlns:dp="data:,dp"
>exclude-result-prefixes="dp xs"
>>
>
>\xC2  <xsl:template match="data">
>\xC2  \xC2  <html>
>\xC2  \xC2  \xC2  <xsl:for-each-group group-by="dp:s(.)" select="period">
><p>
>\xC2 <xsl:value-of select="current-grouping-key()"/>
>\xC2 <xsl:text> </xsl:text>
>\xC2 <xsl:value-of select="sum(current-group()/cost)"/>
></p>
>\xC2  \xC2  \xC2  </xsl:for-each-group>
>\xC2  \xC2  </html>
>\xC2  </xsl:template>
>
>\xC2  <xsl:function name="dp:s">
>\xC2  \xC2  <xsl:param name="p" as="element(period)"/>
>\xC2  \xC2  <xsl:sequence select="$p/concat(start/date,':', 3 *
(xs:int(substring-before(start/time,':')) idiv 3))"/>
>\xC2  </xsl:function>
>\xC2  \xC2  \xC2
></xsl:stylesheet>
>
>
>
>
>On Fri, 2 Jan 2026 at 14:50, Dave Pawson
<mailto:dave.pawson@xxxxxxxxx>dave.pawson@xxxxxxxxx
<<mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>xsl-list-service@xxxxxxxxxxx
rrytech.com> wrote:
>Even easier
><https://privatebin.net/?1306eef3a715a90d#75Jfu1qzHcNaEdno9PyuBj4mq4N695bUJB
8WPHwAhoAw>https://privatebin.net/?1306eef3a715a90d#75Jfu1qzHcNaEdno9PyuBj4mq
4N695bUJB8WPHwAhoAw
>
>a full months worth.
>
>I'd forgotten about pastebin!
>
>regards
>
>
>--
>Dave Pawson
>XSLT XSL-FO FAQ.
>Docbook FAQ.
><http://www.mulberrytech.com/xsl/xsl-list>XSL-List info and archive
><http://lists.mulberrytech.com/unsub/xsl-list/2739265>EasyUnsubscribe (by
email)
>
><http://www.mulberrytech.com/xsl/xsl-list>XSL-List info and archive
><http://lists.mulberrytech.com/unsub/xsl-list/2607481>EasyUnsubscribe (by
email)
>
>
>
>--
>Dave Pawson
>XSLT XSL-FO FAQ.
>Docbook FAQ.
><http://www.mulberrytech.com/xsl/xsl-list>XSL-List info and archive
><http://lists.mulberrytech.com/unsub/xsl-list/96802>EasyUnsubscribe (<>by
email)


--
Contact info, blog, articles, etc. http://www.CraneSoftwrights.com/s/ |
Check our site for free XML, XSLT, XSL-FO and UBL developer resources |
Streaming hands-on XSLT/XPath 2 training class @US$50 (5 hours free!) |
Essays (UBL, XML, etc.) http://www.linkedin.com/today/author/gkholman |

Current Thread