RE: [xsl] current-group () function trouble

Subject: RE: [xsl] current-group () function trouble
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Wed, 9 Mar 2005 20:14:47 -0000
Without seeing your data, it's hard write code for you. The obvious thing is
just to extrapolate from levels 1 2 and 3 to levels 4 and 5, you've
presumably tried that, so it would be nice to see your attempt so we can
find out where the misunderstanding is.

For this kind of nested grouping a recursive solution that reuses the same
processing logic at each level is much more elegant. Extracting the common
code, it seems to be something like this:

<xsl:variable name="$levels" select="'OneHead', 'TwoHead',
'ThreeHead',..."/>

<xsl:template name="process-group">
  <xsl:param name="input" as="element()*"/>
  <xsl:param name="level" as="xs:integer"/>
  <xsl:for-each-group select="$input"
     group-starting-with="*[name()=$levels[$level]]">
    <xsl:choose>
      <xsl:when test="name()=$levels[$level]">
        <section>
          <xsl:call-template name="addId"/>
          <xsl:apply-templates select="."/>
          <xsl:call-template name="process-group">
            <xsl:with-param name="input"
select="current-group()[position()!=1]"/>
            <xsl:with-param name="level" select="$level+1"/>
          </
        </
      </
      <xsl:otherwise>
        <xsl:apply-templates select="current-group()"/>
      </

If you restructure the code like this, adding extra levels becomes child's
play, because each level is processed in the same way.

Michael Kay
http://www.saxonica.com/  

> -----Original Message-----
> From: Kessler, Marcy [mailto:marcy.kessler@xxxxxx] 
> Sent: 09 March 2005 17:13
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] current-group () function trouble
> 
>  
> Hello All -
> 
> I don't think I understand how the current-group () function works
> exactly.  What I want to do is add "FourHead" and "FiveHead" to the
> following code.  I've attempted to modify this code to accomplish this
> and finally got it to be both well-formed in XMLSpy and not have any
> errors when processing (using Saxon 8.3).  However, with my changes, I
> lose data in the output xml files.
> 
> The following is the original code.  Can any of you help me with
> understanding how I need to change this to add these elements?
> 
> Thank you,
> Marcy (still a newbie, but learning)
> 
> 
> <xsl:apply-templates select="current-group()[self::OneHead]" />
>            <xsl:for-each-group select="current-group() except ."
> group-starting-with="TwoHead">
>              <xsl:choose>
>                <xsl:when test="self::TwoHead">
>                  <section>
>                    <xsl:call-template name="addId"/>
>                    <xsl:apply-templates
> select="current-group()[self::TwoHead]"/>
>                    <xsl:for-each-group 
> select="current-group() except ."
>                                        
> group-starting-with="ThreeHead">
>                    <xsl:choose>
>                      <xsl:when test="self::ThreeHead">
>                        <section>
>                          <xsl:call-template name="addId"/>
>                          <xsl:apply-templates
> select="current-group()[self::*]"/>
>                        </section>
>                      </xsl:when>
>                      <xsl:otherwise>
>                        <xsl:apply-templates
> select="current-group()[self::*]"/>
>                      </xsl:otherwise>
>                    </xsl:choose>
>                    </xsl:for-each-group>
>                  </section>
>                </xsl:when>              
>                <xsl:otherwise>
>                  <xsl:for-each-group select="current-group()"
>                                      group-starting-with="ThreeHead">
>                  <xsl:choose>
>                    <xsl:when test="self::ThreeHead">
>                      <section>
>                        <xsl:call-template name="addId"/>
>                        <xsl:apply-templates
> select="current-group()[self::*]"/>
>                      </section>
>                    </xsl:when>
>                    <xsl:otherwise>
>                      <xsl:apply-templates
> select="current-group()[self::*]"/>
>                    </xsl:otherwise>
>                  </xsl:choose>
>                  </xsl:for-each-group>
>                </xsl:otherwise>
>              </xsl:choose>
>            </xsl:for-each-group>
>          </section>
>          </generic>
>      </c_support_doc>
>      </xsl:result-document>      
>      </xsl:for-each-group> 	
>   </xsl:template>

Current Thread