[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

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


Subject: Re: [xsl] Group elements based on summing values (XSL 1.0)
From: "Kevin Bird kevinbrianbird@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 6 Feb 2015 13:40:22 -0000

Hi Michael,

Many thanks for the help.

--
Kevin

-----Original Message-----
From: Michael Kay mike@xxxxxxxxxxxx
[mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx] 
Sent: 06 February 2015 11:44
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] Group elements based on summing values (XSL 1.0)

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
Keywords
xsl