[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: XSL Table Styling

Subject: Re: XSL Table Styling
From: Mike Brown <mike@xxxxxxxx>
Date: Wed, 19 Jul 2000 10:20:30 -0700 (PDT)
xsl table
Scott Johnson wrote:
> What I'm trying to do is lay out two rows of data with 4 items per row

Generally when people ask questions about HTML tables, they've tried a
tag-based approach, which inevitably fails because they are thinking
about how to arbitrarily declare the beginning and end of each row. In
the well-formed world of XML and XSLT, one needs a more object-oriented
approach. If you break the problem down into the answers to these
questions, you might see your solution more quickly:

 - What always determines when a new row is added?
 - What always goes into each row?
 - What always goes into each cell?

In your case, for each "row" of data, you're wanting to create 3 table
rows. Your stylesheet is trying to create a new set of table rows for
each *unit* of data (each 'hit' element that is matched), so of course
you end up with too many table rows and not enough columns in your
table.

I'm guessing your XML looks something like

<result>
  <hit>
    <name>Foo</name>
    <small-image>foo.jpg</small-image>
    <short-desc>This is foo.</short-desc>
  </hit>
  ...
</result>

Here is one way to approach the problem, and it is flexible for any
number of desired columns with an unknown number of 'hit' elements.
It will also fill in cells in empty columns, in case the number of
'hit' elements isn't evenly divisible by the number of columns
desired. (untested code; watch for typos)

<xsl:template match="result">
  <xsl:variable name="cols" select="4"/>
  <xsl:variable name="all_hits" select="hit"/>
  <table>
    <!-- start a new data row for every 1st, 5th, 9th, etc. 'hit' element -->
    <xsl:for-each select="$all_hits[position() mod $cols = 1]">
      <xsl:variable name="this_hit_pos" select="position()"/>
      <xsl:variable name="current_row_hits" select="$all_hits[position() &gt;= $this_hit_pos and position() &lt; $this_hit_pos + $cols]"/>
      <!-- go generate the 3 table rows for this one data row -->
      <xsl:call-template name="make_table_rows">
        <xsl:with-param name="cols" select="$cols"/>
        <xsl:with-param name="current_row_hits" select="$current_row_hits"/>
      </xsl:call-template>
    </xsl:for-each>
  </table>
</xsl:template>

<xsl:template name="make_table_rows">
  <xsl:param name="cols" select="1"/>
  <xsl:param name="current_row_hits" select="/.."/>
  <!-- selects above are defaults in case nothing was passed in -->
  <xsl:if test="$current_row_hits">
    <xsl:variable name="num_empty_cols" select="$cols - $current_row_hits"/>
    <tr>
      <xsl:for-each select="$current_row_hits">
        <td width="175">
          <img width="175" height="175" src="{small-image}"/>
        </td>
      </xsl:for-each>
      <xsl:if test="$num_empty_cols"> <!-- true if not zero -->
        <xsl:call-template name="make_empty_cells">
          <xsl:with-param name="num" select="$num_empty_cols"/>
        </xsl:call-template>
      </xsl:if>
    </tr>
    <tr>
      <xsl:for-each select="$current_row_hits">
        <td width="175">
          <font face="Verdana" size="2">
            <b>
              <xsl:value-of select="name"/>
            </b>
          </font>
        </td>
      </xsl:for-each>
      <xsl:if test="$num_empty_cols"> <!-- true if not zero -->
        <xsl:call-template name="make_empty_cells">
          <xsl:with-param name="num" select="$num_empty_cols"/>
        </xsl:call-template>
      </xsl:if>
    </tr>
    <tr>
      <xsl:for-each select="$current_row_hits">
        <td width="175">
          <font face="Verdana" size="1">
            <xsl:value-of select="short-desc"/>
          </font>
        </td>
      </xsl:for-each>
      <xsl:if test="$num_empty_cols"> <!-- true if not zero -->
        <xsl:call-template name="make_empty_cells">
          <xsl:with-param name="num" select="$num_empty_cols"/>
        </xsl:call-template>
      </xsl:if>
    </tr>
  </xsl:if>
</xsl:template>

<xsl:template name="make_empty_cells">
  <xsl:with-param name="num" select="0"/>
  <xsl:if test="$num">
    <td>&#160;</td>
    <xsl:call-template name="make_empty_cells">
      <xsl:with-param name="num - 1"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

-Mike


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.