Re: [xsl] generate unknow table

Subject: Re: [xsl] generate unknow table
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Tue, 12 Jun 2001 09:47:54 +0100
Hi John,

> What I want is to generate a XSL that can create HTML <table>
> whether the <sel> field will be display or not is determined by the
> flag80 attribute in the <sel> element in <record> element. if
> flag80="on", the <sel> field will be shown, otherwise, it won't be
> shown.

As I understand it from this and your previous messages, the field
elements in your title element indicate the columns on your table. All
those columns are always there. The record elements represent the
rows, and the child elements within that give the data for the row.
The cells in the row need to appear in the same order as indicated by
the id attributes of the field elements in the title. If one of the
field elements has an ND attribute on it, then the value of that is
the name of an attribute on one of the child elements or the record
element; if that attribute is present with a value of 'off', then the
data is suppressed (there's still a table cell, but it's empty).

If I've got that right, here's a solution.  First, collect together
the column information (the title fields) into a variable so that you
can access it easily:

<xsl:variable name="columns" select="display/title/field" />

Now, the table can be created in a template matching the display
element.  The headers of the table are taken from the values of the
field elements (in $columns).  The body of the table is created by
applying templates to the record elements:

<xsl:template match="display">
         <xsl:for-each select="$columns">
            <th><xsl:value-of select="." /></th>
      <xsl:apply-templates select="data/record" />

The template for a record element needs to use the information in the
$columns variable to determine the order in which the cells are
accessed, and to work out whether to suppress the content of the cell
or not.  You need to cycle through the field elements (in the $columns
variable) to get the name of the element that you want to access, and
to work out what the name of the flag attribute is.

The important pattern here is working out how to select an element or
attribute when you have the name of that element or attribute.  To do
this, you select *all* elements/attributes and then test the name() of
the node against the value that you're after.  For example, to get the
data for a particular column for a particular record:

  $record/*[name() = $field-id]

Putting it together, the template looks like:

<xsl:template match="record">
   <xsl:variable name="record" select="." />
      <xsl:for-each select="$columns">
         <xsl:variable name="field-id" select="@id" />
         <xsl:variable name="flag-attr" select="@ND" />
         <xsl:variable name="data"
                       select="$record/*[name() = $field-id]" />
               <xsl:when test="not($flag-attr) or
                               $data/@*[name() = $flag-attr] = 'on'">
                  <xsl:value-of select="$data" />

I hope that helps,


Jeni Tennison

 XSL-List info and archive:

Current Thread