[xsl] complex table header

Subject: [xsl] complex table header
From: "Angela Williams" <Angela.Williams@xxxxxxxxxxxxxxxxxx>
Date: Wed, 7 Feb 2007 08:03:09 -0600
We're creating an in-house content mgmt system and I am trying to define the
xml and xsl to let the user change the title values in a pre-defined table
format. In addition to changing the text in the headers, the user needs to be
able to reorder the columns.

I'm stuck trying to create rules to format the table in a generic manner with
this complexity.  I create the appropriate number of columns and can calculate
how many rows I should have, but then I can't figure out how to actually
populate the rows correctly. I would appreciate any tips or suggestions in
solving this problem.

I'm using XSLT 2.0, XEP 4.4 and Saxon8B.

Note: The reference to Girl Scout cookies is just because I am head over heels
in cases of them until my daughter sells them all. There really is a more
pressing need for this. :-)

Thanks!
Angela Williams

Desired Output:

           --------------- 2007 Cookies -----------------
                           ----------- Flavors ----------
           --- Price ----  ---- Best Sellers ----
Girl Scout | Box | Case |  Thin Mints | Caramels | Others | Mom | Phone 


XML:

<!-- The xml data is assumed to have an implicit document sort of columns
     left to right and rows top to bottom. The rows need to be built bottom
     to top, with 'column' elems on bottom, the deepest column-group next to
     bottom and so on, with the shallowest column-group in the top row.

     I have freedom to change the xml structure as needed.  The structure is
     great for my purposes if I don't have to worry about spanning columns.
-->
<columns>
   <column>Girl Scout</column>

   <column-group>
      <span>2007 Cookies</span>

      <column-group>
         <span>Price</span>
         <column>Box</column>
         <column>Case</column>
      </column-group>

      <column-group>
         <span>Flavors</span>
         <column-group>
            <span>Best Sellers</span>
            <column>Thin Mint</column>
            <column>Caramels</column>
         </column-group>

         <column>Others</column>
      </column-group>
   </column-group>

   <column>Mom</column>

   <column>Phone</column>
</columns>

XSLT:

   <xsl:template match="columns">
      <fo:block-container>
         <fo:table xsl:use-attribute-sets="table">
            <fo:table-header>

               <xsl:apply-templates select="descendant-or-self::column" />

               <xsl:variable name="depth">
                  <xsl:value-of select="fc:depth(.,1)" />
               </xsl:variable>

            </fo:table-header>
         </fo:table>
      </fo:block-container>
   </xsl:template>

   <xsl:template match="column">
      <xsl:choose>
         <xsl:when test="position()=1">
            <fo:table-column
                column-number="1"
                column-width="proportional-column-width(1)"
            />
         </xsl:when>
         <xsl:otherwise>
            <fo:table-column column-width=".60in">
               <xsl:attribute name="column-number">
                  <xsl:value-of select="position()" />
               </xsl:attribute>
            </fo:table-column>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

   <!--
        Used to determine the number of rows in the table header.
        I get the right count but don't know what to do with it.
    -->
   <xsl:function name="fc:depth">
      <xsl:param name="curr-group" />
      <xsl:param name="depth" />

      <xsl:choose>
         <xsl:when test="$curr-group/column-group">
            <xsl:value-of
                select="fc:depth($curr-group/column-group, depth+1)"
            />
         </xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="$depth" />
         </xsl:otherwise>
      </xsl:choose>
   </xsl:function>

Current Thread