Hello,
The following stylesheet does what I need, but I find it very ugly.
The idea is that I have an unsorted XML source as:
<fotos>
<foto id="3" />
<foto id="1" />
<foto id="2" />
...
<foto id="NNN" />
</fotos>
The quantity of <foto/> is not determined.
I would like to generate a "photo index", i.e. a picture containing
small versions of all photos, arranged by rows of 8 photos.
I can make it dynamically adaptable by simply sticking the photos one to
the other, but I'd prefer to have the image arranged as a table, with
eight cells per row.
Additionally, I would like to add blank cells at the end so that the
last row is complete.
Eventually (not done on this stylesheet), I may want to add a "logo"
image at the end, as if one more photo was present on the XML source.
Here's the "beast":
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<html><body>
<table border="0" cellpadding="0" cellspacing="0">
<xsl:for-each select="fotos/foto[(@id mod 8) = 1]">
<xsl:sort order="ascending" select="@id" data-type="number" />
<tr>
<xsl:apply-templates
select="../foto[@id>=current()/@id][current()/@id+8>@id]">
<xsl:sort order="ascending" select="@id" data-type="number" />
</xsl:apply-templates>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][1])">
<td> </td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][2])">
<td> </td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][3])">
<td> </td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][4])">
<td> </td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][5])">
<td> </td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][6])">
<td> </td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][7])">
<td> </td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][8])">
<td> </td>
</xsl:if>
</tr>
</xsl:for-each>
</table>
</body></html>
</xsl:template>
<xsl:template match="foto">
<td><a href="{@id}.jpg"><img border="0" src="{@id}.small.jpg" /></a></td>
</xsl:template>
</xsl:stylesheet>
Comments on what I dislike:
I dislike using [(@id mod 8) = 1], but I am afraid I cannot do that much
differently.
I dislike the ../[@id>=current()/@id][current()/@id+8>@id] couple of
conditions which give me the eight <foto/> that are to be in the same
row as the first one. I am pretty sure that it can be done better.
But what I especially dislike (like in hate) the way I completed the
last (or any photo-missing intermediate) row. That is, the eight xsl:if
conditions that fill the right of the row.
Moreover, I dislike the fact that I count on the IDs not only for order
but also for placement. I would like to be able to remove a photo if I
wish, without changing the other photo's ID.
So, for this last reason, I'm afraid a serious change has to be done to
the stylesheet. But I could not think of how to do it when I wrote the
stylesheet yesterday.
Any hints? Maybe keys may help? If so, how?
Thank you very much.
Antonio Fiol
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list