xsl-list
[Top] [All Lists]

Re: Transform list of elements to a sorted and dynamic HTML table

2004-12-12 06:08:01
Hi,

so for the sorting of the elements I worked out the following, rather simple
and perhaps not quite elegant solution:

<xsl:variable name="Rows">3</xsl:variable>
<xsl:variable name="Columns">4</xsl:variable>
<xsl:variable name="SortedItems">
 <xsl:for-each select="//item">
   <xsl:sort select="date" order="descending"/>
   <xsl:sort select="name" order="ascending"/>
   <xsl:if test="position() le $Rows * $Columns">
     <xsl:sequence select="."/>
   </xsl:if>
 </xsl:for-each>
</xsl:variable>

Now I have <$Rows * $Columns> items in the right order in $SortedItems and
may call them by this:

<xsl:for-each select="$SortedItems/item">
 <xsl:message select="position(),': ',name"/>
</xsl:for-each>

If this really is what I need ... we'll see.

@Geert: I will try out your idea after a shower and breakfast and then
post experiences here.

Regards,
Jannis


Geert Josten schrieb:

Hi,

The easiest way of achieving this is by first sorting your items and then trying to put them into columns. Once the items are sorted, you can do something like:

<xsl:template match="item">
  <xsl:if test="position() mod $columns = 1 or $columns = 1">
    <tr>
      <xsl:variable name="nextpos" select="position() + $columns" />
<xsl:apply-templates select=".|following-sibling::item[$nextpos > position()]" mode="column"/>
    </tr>
  </xsl:if>
</xsl:template>

<xsl:template match="item" mode="column">
    <td>
      <xsl:apply-templates select="node()"/>
    </td>
</xsl:template>

You need to sort in a separate step (two stylesheets or something like building a document fragment with sorted items or so) as the following-sibling axis always works on document order, which is not what you would like here...

Cheers,
Geert

Jannis Pohlmann wrote:

Good morning,

I have a list of items, e.g.:

<item>
 <name>Adoreable</name>
 <date>2004-12-11</date>
</item>
<item>
 <name>Adjustable</name>
 <date>2004-12-11</date>
</item>
<item>
 <name>Bulk</name>
 <date>2004-12-10</date>
</item>
<item>
 <name>Condensed</name>
 <date>2004-12-12</date>
</item>
<item>
 <name>Compromise</name>
 <date>2004-11-08</date>
</item>

and I want them to be transformed to a sorted and dynamic (columns and rows adjustable by variables - $Columns and $Rows) HTML table (using recent Version of Saxon and XSLT2.0). The sort element are the <date/>-Elements (descending), so the table output had to look like this ($Columns = 2, $Rows = 2):

<table>
 <tr>
   <td>Condensed</td>
   <td>Adjustable</td>
 </tr>
 <tr>
   <td>Adoreable</td>
   <td>Bulk</td>
 </tr>
 <tr>
   <td colspan="2">Compromise</td>
 </tr>
</table>

If there are not enough items to fill the columns of the last row its last <td> should have a "colspan" attribute in order to satisfy layout requirements. No empty rows should be created (e.g. if there are not enough items to fill all <$Rows> rows).

As you may see there exists a second sort element (<name/>, ascending) in my example
but this is no must-have feature.

An alternative way might be to select the first <$Columns * $Rows> items (sorted descendingly by <date/>, of course) - but I see no solution for this, right now.

Is there a way to handle this problem with the power of XSLT?
Regards,
Jannis


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--