Re: [xsl] Grouping and Sum problem - XSL 1.0

Subject: Re: [xsl] Grouping and Sum problem - XSL 1.0
From: Florent Georges <lists@xxxxxxxxxxxx>
Date: Thu, 1 May 2008 16:07:09 +0200 (CEST)
Mike Finch wrote:

  Hi

> Im trying to sum the total royalty for both the row which is
> type RELEASE as well as the following siblings royalties
> which have the same releaseid as well as same order number
> as the preceding RELEASE row.

  I didn't follow this thread closely, so I maybe missed some
info.  But I wonder if you really need grouping.  From the
example you showed up, I would rather use the sibling walking
pattern.

  You walk over the row one after the other.  Once you detect
the special RELEASE case you switch to another mode that sums
up the royalties.  Once you detect you eat up all the row to
ignore you add the special row to the output tree, with the
royalties sum, and you get back to the regular sibling walk.

  Here is an example that produces the desired output with
your sample input:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

   <xsl:output indent="yes"/>

   <!-- Copy template pattern. -->
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

   <!-- Initiate the sibling walking. -->
   <xsl:template match="document">
      <xsl:copy>
         <xsl:apply-templates select="@*|row[1]"/>
      </xsl:copy>
   </xsl:template>

   <!-- The actual sibling walking. -->
   <xsl:template match="row">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
      <xsl:apply-templates select="following-sibling::*[1]"/>
   </xsl:template>

   <!-- The special case "eating up" some following siblings. -->
   <xsl:template match="row[type = 'RELEASE']">
      <xsl:apply-templates
          mode="eat-up" select="following-sibling::*[1]">
         <xsl:with-param name="royalty" select="royalty"/>
         <xsl:with-param name="row"     select="."/>
      </xsl:apply-templates>
   </xsl:template>

   <!-- Eat up this row or take again the sibling walking? -->
   <xsl:template match="row" mode="eat-up">
      <xsl:param name="royalty"/>
      <xsl:param name="row"/>
      <xsl:variable name="prev-id" select="
          preceding-sibling::row[1]/releaseid"/>
      <xsl:choose>
         <!-- Continue eating up and summing royalties. -->
         <xsl:when test="
             order = $row/order
                 and ( not($prev-id) or releaseid = $prev-id )">
            <xsl:apply-templates
                mode="eat-up" select="following-sibling::*[1]">
               <xsl:with-param name="royalty" select="
                   $royalty + royalty"/>
               <xsl:with-param name="row"     select="$row"/>
            </xsl:apply-templates>
         </xsl:when>
         <!-- Come back on the sibling walking path, after having
              added the previous row to the result tree. -->
         <xsl:otherwise>
            <xsl:element name="{ name($row) }">
               <xsl:apply-templates select="
                   $row/@*|$row/*[not(self::royalty)]|$prev-id"/>
               <royalty>
                  <xsl:value-of select="$royalty"/>
               </royalty>
            </xsl:element>
            <xsl:apply-templates select="."/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

</xsl:stylesheet>

  BTW, are you sure you are stuck to XSLT 1.0?  And for good reasons? 
Or is it just "by habit"?

  Regards,

--drkm
























__________________________________________________
Do You Yahoo!?
En finir avec le spam? Yahoo! Mail vous offre la meilleure protection possible contre les messages non sollicitis 
http://mail.yahoo.fr Yahoo! Mail 

Current Thread