Re: [xsl] Extracting the grouping from a flat structure

Subject: Re: [xsl] Extracting the grouping from a flat structure
From: Kevin Jones <kjones@xxxxxxxxxxx>
Date: Mon, 13 Dec 2004 11:42:43 +0000
Hi Peter,

Give the version below a try. It's really the same algorithm 
but I have replaced the nodeset chopping by some guided 
searching of the document. This appears to be much easier 
for Xalan to handle.

Kev.

 <xsl:template match='table'>
  <xsl:variable name="postable">
   <index>
   <xsl:for-each select="tr">
    <xsl:if test="th">
     <pos><xsl:value-of select="position()"/></pos>
    </xsl:if>
   </xsl:for-each>
   </index>
  </xsl:variable>
  
  <xsl:variable name="headers" select="tr[th]"/>
  <xsl:for-each select="$headers[1]">
   <xsl:call-template name="walk">
    <xsl:with-param name="headers" 
select="$headers[position()>1]"/>
    <xsl:with-param name="pos" 
select="xalan:nodeset($postable)/index/pos"/>
   </xsl:call-template>
  </xsl:for-each>
 </xsl:template>
 
 <xsl:template name="walk">
  <xsl:param name="headers"/>
  <xsl:param name="pos"/>
  <xsl:choose>
   <xsl:when test="count($pos)=0"/>
   <xsl:when test="count($pos)=1">
    <header>
     <xsl:copy-of select="."/>
     <xsl:for-each 
select="following-sibling::*[position()>1]">
      <row>
       <xsl:copy-of select="."/>
      </row>
     </xsl:for-each>
    </header>
   </xsl:when>
   <xsl:otherwise>
    <header>
     <xsl:copy-of select="."/>
     <xsl:variable name="rows" select="$pos[2]-$pos[1]"/>
     <xsl:for-each 
select="following-sibling::*[1]/following-sibling::*[position()&lt;
$rows]">
      <row>
       <xsl:copy-of select="."/>
      </row>
     </xsl:for-each>
    </header>
    <xsl:for-each select="$headers[1]">
     <xsl:call-template name="walk">
      <xsl:with-param name="headers" 
select="$headers[position()>1]"/>
      <xsl:with-param name="pos" 
select="$pos[position()>1]"/>
     </xsl:call-template>
    </xsl:for-each>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

Current Thread