This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Making groups of N elements --> Photo index


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>&#xa0;</td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][2])">
<td>&#xa0;</td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][3])">
<td>&#xa0;</td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][4])">
<td>&#xa0;</td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][5])">
<td>&#xa0;</td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][6])">
<td>&#xa0;</td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][7])">
<td>&#xa0;</td>
</xsl:if>
<xsl:if test="not(../foto[@id>=current()/@id][current()/@id+8>@id][8])">
<td>&#xa0;</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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]