[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Referencing nodes from an out-of-scope xsl:for-each loop


Subject: Re: [xsl] Referencing nodes from an out-of-scope xsl:for-each loop
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Sat, 19 May 2001 08:53:16 +0100

Hi Joel,

> But I am really wanting to do more complex stuff, such as this:
>
>   <display-columns>
>     <column label="Name">
>       <link>
>         <label>
>           <B><sql-field name="title"/></B>
>         </label>
>         <href>
>           /viewarea.asp?where=<sql-field name="location"/>
>         </href>
>      </link>
>     </column>
>   </display-columns>
>
> .. in this way permitting versatile display formatting options while
> minimizing xsl work.

First, you want to iterate over the row elements, creating a row for
each. Within that row, you want to iterate over each of the column
elements within the display-columns element, for that particular row.
The easiest way of doing this is pass a parameter indicating the
current row into a template that matches a column. So your
sql-recordset template should look something like:

<xsl:template match="sql-recordset">
   <xsl:variable name="columns" select="display-columns/column" />
   <xsl:for-each select="row">
      <tr>
         <xsl:apply-templates select="$columns">
            <xsl:with-param name="row" select="." />
         </xsl:apply-templates>
      </tr>
   </xsl:for-each>
</xsl:template>

Now, you need a template that matches the column element and adds a td
element to indicate the cell.  You then want to make up the content of
that cell based on the content of the column element.  You can do that
by applying templates to its content, again passing the parameter
along to indicate what row you're currently on:

<xsl:template match="column">
   <xsl:param name="row" />
   <td>
      <xsl:apply-templates>
         <xsl:with-param name="row" select="$row" />
      </xsl:apply-templates>
   </td>
</xsl:template>

It's wise when you have this kind of parameter passing to set up a
generic template that passes the parameter on to the next level -
otherwise you might lose it my missing having a template for a
particular element.  In your case, you probably want to copy elements
by default as well, so have a template like:

<xsl:template match="*">
   <xsl:param name="row" />
   <xsl:copy>
      <xsl:apply-templates>
         <xsl:with-param name="row" select="$row" />
      </xsl:apply-templates>
   </xsl:copy>
</xsl:template>

There are some exceptions to this copying behaviour. When you come
across the link element, presumably you want to make an a element with
an href attribute determined by the href child of the link and the
content determined by the label child of the link. You need a template
like the following (keep passing the row down):

<xsl:template match="link">
   <xsl:param name="row" />
   <a>
      <xsl:apply-templates select="href">
         <xsl:with-param name="row" select="$row" />
      </xsl:apply-templates>
      <xsl:apply-templates select="label">
         <xsl:with-param name="row" select="$row" />
      </xsl:apply-templates>
   </a>
</xsl:template>

<xsl:template match="href">
   <xsl:param name="row" />
   <xsl:attribute name="href">
      <xsl:apply-templates>
         <xsl:with-param name="row" select="$row" />
      </xsl:apply-templates>
   </xsl:attribute>
</xsl:template>

The text can take care of itself - it'll just get copied (although you
might want to normalize it first, to get rid of the whitespace).

The sql-field elements need to be treated specially.  It's at this
point that you finally *use* the $row parameter to identify the data
from the row.  You can get it by looking at the attribute on the row
that has the same name as the name attribute on the sql-field:

<xsl:template match="sql-field">
   <xsl:param name="row" />
   <xsl:variable name="name" select="@name" />
   <xsl:value-of select="$row/@*[name() = $name]" />
</xsl:template>

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
Keywords
xsl