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]

Re: Filling table cells with <item>s


Hello Steve, you don't need to calculate the tables are something similar.
You only have to say "a new table for every 6th element", the same for a new
row. So the stylesheet is relative simple:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:param name="cols" select="2"/>
<xsl:param name="rows" select="3"/>
<xsl:param name="by" select="'col'"/>

<xsl:template match="root">
    <html>
        <head></head>
        <body>
            <xsl:apply-templates select="item[position() mod ($rows * $cols)
= 1]" mode="table"/>
        </body>
    </html>
</xsl:template>

<xsl:template match="item" mode="table">
    <table border="1">
        <xsl:variable name="items-in-this-table" select=". |
following-sibling::item[position() &lt; ($rows * $cols)]"/>
        <xsl:choose>
            <xsl:when test="$by = 'row'">
                <xsl:apply-templates select="$items-in-this-table[position()
mod $cols = 1]" mode="row"/>
            </xsl:when>
            <xsl:when test="$by = 'col'">
                <xsl:apply-templates select="$items-in-this-table[position()
&lt;= $rows]" mode="row"/>
            </xsl:when>
        </xsl:choose>
        <!-- here you can implement some logic for filling the last table,
if there are not enough items to fill all <td>s -->
    </table>
</xsl:template>

<xsl:template match="item" mode="row">
    <tr>
        <xsl:choose>
            <xsl:when test="$by = 'row'">
                <xsl:apply-templates select=". |
following-sibling::item[position() &lt; $cols]"/>
            </xsl:when>
            <xsl:when test="$by = 'col'">
                <xsl:apply-templates select="(. |
following-sibling::item)[position() &lt; ($cols * $rows)][position() mod
$rows = 1]"/>
            </xsl:when>
        </xsl:choose>
    </tr>
</xsl:template>

<xsl:template match="item">
    <td>
        <xsl:value-of select="."/>
    </td>
</xsl:template>

</xsl:stylesheet>

At first you access the item elements which should create a new table (every
6th item), so have to access every item element whose positions are 1
(counting 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,...). This happens with "mod". The
second step is to access the current ( here: . ) item again and all its
following-sibling 2,3,4,5, of course with a new mode. This is done twice
(new table, new row) and everything is done.
When filling the table by col there must be used another logic. You can't
create the tables in HTML by cols. So we create a new <tr> for the first
$rows elements in this table. And then every $rows'th following element must
be added to this row.
1 bug: 1 row or 1 col isn't possible for one or the other. Any number mod 1
is always 0 ... but there is no element with position() 0. But you can fix
this too, if you need it. It's a bit more to write.

Hope this helps,

Joerg

> If each table must have nrows and ncols, then a total of
>
>   ntables=ceiling(n/(nrows*ncols))
>
> tables are necessary to exhaust all of the <item>s with the
> last table possibly having some empty cells. For example
> if n=15, nrows=3 and ncols=2, ntable=3 and the three tables
> would be arranged one after the other as follows:
>
>    +------+------+
>    |item01|item02|
>    +------+------+
>    |item03|item04|
>    +------+------+
>    |item05|item06|
>    +------+------+
>
>    +------+------+
>    |item07|item08|
>    +------+------+
>    |item09|item10|
>    +------+------+
>    |item11|item12|
>    +------+------+
>
>    +------+------+
>    |item13|item14|
>    +------+------+
>    |item15|      |
>    +------+------+
>    |      |      |
>    +------+------+
>
> Also, I would like the option to fill the tables up by
> rows (as shown above) or by columns:
>
>    +------+------+
>    |item01|item04|
>    +------+------+
>    |item02|item05|
>    +------+------+
>    |item03|item06|
>    +------+------+
>
> How would you go about implementing this in XSLT given
> parameters nrows, ncols, by={"cols","rows"}? I am having
> some trouble determining what my "outer" loop is since there
> is the possibility of some empty cells (I can't just process
> each <item>). Thx in advance.



 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]