Hay un error en la salida sugerido, como <img/>
elementos deben tener alt
atributos en cada versión de HTML en la que están presentes.
De todos modos, lo siguiente hace esto, pero sin los atributos que se pueden hacer desde CSS (para mantener el tamaño). Añadiéndolos de nuevo si se desea es trivial:
<xsl:template match="pics">
<table>
<xsl:apply-templates select="pic[position() mod 3 = 1]"/>
</table>
</xsl:template>
<xsl:template match="pic[position() mod 3 = 1]">
<tr>
<td>
<xsl:if test="2 > count(following-sibling::pic)">
<xsl:attribute name="colspan">
<xsl:value-of select="3 - count(following-sibling::pic)"/>
</xsl:attribute>
</xsl:if>
<img src="{.}" alt="" />
</td>
<xsl:apply-templates select="following-sibling::pic[3 > position()]" />
</tr>
</xsl:template>
<xsl:template match="pic">
<td><img src="{.}" alt=""/></td>
</xsl:template>
Lo anterior presupone que desea que la ruta del archivo utilizado directamente, añadiendo código para transformarlo de alguna manera (decir tomando sólo la última parte de la ruta utilizando substring-after()
) no es una extensión difícil, suponiendo que dicha transformación no se complica por sí misma.
Editar:
Yo y JohnB van a más territorio aquí, los anteriores basta para responder a la pregunta original.
Agregado para dar una respuesta más completa a la pregunta de JohnB. El siguiente es el código equivalente que usa for-each en lugar de apply-templates. En teoría, tanto una implementación secuencial como una base de máquina de estado de un procesador XSLT deberían tratar esto de manera idéntica, aunque puede encontrar diferencias en la práctica (si me dijera que eran diferentes con un procesador determinado, apostaría una pequeña cantidad en él). siendo un poco más rápido con el procesamiento secuencial y un poco más lento con el procesamiento de máquina de estado, pero solo apostaría una cantidad muy pequeña).
Tenga en cuenta que no podemos reutilizar la plantilla predeterminada para pic. En el lado positivo, si tenemos una plantilla predeterminada diferente para la foto en otro lugar (si esto fuera parte de una hoja de estilo mucho más complicada), no necesitamos ser listos para diferenciarlos, que es el momento principal que yo personalmente se inclinaría hacia for-each.
<xsl:template match="pics">
<table>
<xsl:for-each select="pic[position() mod 3 = 1]">
<tr>
<td>
<xsl:if test="2 > count(following-sibling::pic)">
<xsl:attribute name="colspan">
<xsl:value-of select="3 - count(following-sibling::pic)"/>
</xsl:attribute>
</xsl:if>
<img src="{.}" alt="" />
</td>
<xsl:for-each select="following-sibling::pic[3 > position()]">
<td><img src="{.}" alt=""/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
Buena pregunta (+1). Vea mi respuesta para una solución completa que está en el espíritu de XSLT y para una explicación de todos los momentos significativos en la solución. :) –