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

Re: Display table where colomns are variable

Subject: Re: Display table where colomns are variable
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Tue, 13 Mar 2001 14:28:47 +0000
display table name
Hi Tim,

> I would like to use a standard template to display data throughout a
> site, but the number of columns required will be different depending
> on the various pieces of data required to be displayed.

Well, the easy way would be to have individual templates for each of
the types of nodes that you want to turn into a row, with each of the
templates choosing what cells to put in the row.  So your
child element template would look like:

<xsl:template match="child">
   <tr>
      <td>
         <xsl:value-of select="firstname">
         <xsl:text> </xsl:text>
         <xsl:value-of select="lastname">
      </td>
      <td><xsl:value-of select="otherthing" /></td>
      ...
   </tr>
</xsl:template>

Now, I assume that you don't want to do that because you want to add
particular formatting to cells in different columns or something, and
that's why you want to have a central template to create the cells?

I think that the best way of approaching this is to use the node-set()
extension function available in whatever processor you're using.
Create a node set that identifies the cells that you want to display,
then work over that node set to output them.  So make your showdata
accept a node set as a parameter, and work over that node set to
create the cells.  You can use the position() of the cell to determine
any column-specific properties of the td:

<xsl:template name="showdata">
   <xsl:param name="cells" select="/.." />
   <xsl:for-each select="$cells">
      <td><xsl:copy-of select="node()" /></td>
   </xsl:for-each>
</xsl:template>

You could call this template with, for example:

<xsl:template match="child">
   <tr>
      <xsl:variable name="cells">
         <cell>
            <xsl:value-of select="firstname">
            <xsl:text> </xsl:text>
            <xsl:value-of select="lastname">
         </cell>
         <cell><xsl:value-of select="otherthing" /></cell>
         ...
      </xsl:variable>
      <xsl:call-template name="showdata">
         <xsl:with-param name="cells"
                         select="exsl:node-set($cells)" />
      </xsl:call-template>
   </tr>
</xsl:template>

Or you may find it simpler just to apply templates to the cell
elements to do it:

<xsl:template match="child">
   <tr>
      <xsl:variable name="cells">
         <cell>
            <xsl:value-of select="firstname">
            <xsl:text> </xsl:text>
            <xsl:value-of select="lastname">
         </cell>
         <cell><xsl:value-of select="otherthing" /></cell>
         ...
      </xsl:variable>
      <xsl:apply-templates select="exsl:node-set($cells)" />
   </tr>
</xsl:template>

and then have the template that matches the cell element add the cell
information - again it can use its particular position() to determine
any column specific formatting:

<xsl:template match="cell">
   <td><xsl:copy-of select="node()" /></td>
</xsl:template>

> <xsl:template name="showdata">
>     <xsl:param name="column1">Null</xsl:param>
>     <xsl:param name="column2">Null</xsl:param>
>     <xsl:param name="column3">Null</xsl:param>
>     <xsl:param name="column4">Null</xsl:param>
>     ...
>     ...
>     <xsl:if test="not($column1='Null')"><td><xsl:value-of select="$column1"
/>></td></xsl:if>
>     <xsl:if test="not($column2='Null')"><td><xsl:value-of select="$column2"
/>></td></xsl:if>
>     <xsl:if test="not($column3='Null')"><td><xsl:value-of select="$column3"
/>></td></xsl:if>
>     <xsl:if test="not($column4='Null')"><td><xsl:value-of select="$column4"
/>></td></xsl:if>
> ...
> ...
> </xsl:template>

Rather than using:

  <xsl:param name="column1">Null</xsl:param>

you should probably use just:

  <xsl:param name="column1" />

and then test whether any value has been passed with:

  <xsl:if test="$column1">
     <td><xsl:value-of select="." /></td>
  </xsl:if>

The disadvantage to this is that you can't tell the difference between
no value being passed and an empty value being passed.  If you want to
use 'Null' as the default value so that you can make that distinction,
then you should probably specify it in the select attribute of the
xsl:param rather than its content:

  <xsl:param name="column1" select="'Null'" />

and then use:

  <xsl:if test="$column1 != 'Null'">
     <td><xsl:value-of select="." /></td>
  </xsl:if>

It just means that the value 'Null' is stored as a string rather than
a result tree fragment.

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 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.