[Home] [By Thread] [By Date] [Recent Entries]
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
|

Cart



