Re: [xsl] Group elements based on summing values (XSL 1.0)

Subject: Re: [xsl] Group elements based on summing values (XSL 1.0)
From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 6 Feb 2015 11:43:30 -0000
It's not an easy problem. Whether in 1.0 or 2.0 you need to use sibling
recursion. The basic structure is: write a template that matches <num>
elements and that calls itself recursively to process the immediately
following sibling element, passing the accumulated total as a parameter.
Within the template, the recursive call to process the next element goes
inside a <group> element if there's room for more entries, or outside the
group element if not: something like

<xsl:template match="num">
  <xsl:param name="total-so-far"/>
  <xsl:choose>
  <xsl:when test="$total-so-far &lt; 10">
     <xsl:copy-of select="."/>
     <xsl:apply-templates select="following-sibling::num[1]">
       <xsl:with-param name="total-so-far" select="$total-so-far + num"/>
     </xsl:apply-templates>
  </xsl:when>
  <xsl:otherwise>
    <group>
       <xsl:copy-of select="."/>
      <xsl:apply-templates select="following-sibling::num[1]">
       <xsl:with-param name="total-so-far" select="0"/>
     </xsl:apply-templates>
    </group>
 </xsl:otherwise>
</xsl:choose>
</xsl:template>

You kick it off with

<xsl:template match="row">
  <xsl:apply-templates select="num[1]">
    <xsl:with-param name="total-so-far" select="0"/>

I may not have got that exactly right, but you get the idea.

Michael Kay
Saxonica
mike@xxxxxxxxxxxx
+44 (0) 118 946 5893




On 6 Feb 2015, at 10:44, Kevin Bird kevinbrianbird@xxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> Hello,
>
> My XSL skills are a bit rusty.
>
> Starting from the first <num> element, I need to create the smallest group
> possible where the sum of the <num> elements totals 10 or more. I am only
> able to use XSL 1.0.
>
> INPUT:
> <row>
>    <num>3</num>
>    <num>4</num>
>    <num>4</num>
>    <num>7</num>
>    <num>12</num>
>    <num>15</num>
>    <num>1</num>
> </row>
>
> OUTPUT:
> <row>
>    <group1>
>        <num>3</num>
>        <num>4</num>
>        <num>4</num>
>    </group1>
>    <group2>
>        <num>7</num>
>        <num>12</num>
>        <num>15</num>
>        <num>1</num>
>    </group2>
> </row>
>
> Any help/pointers appreciated.
>
> --
> Kevin

Current Thread