Subject: Re: [xsl] Changing table output from horizontal to vertical From: "Mark" <mark@xxxxxxxxxxxx> Date: Sun, 18 Sep 2011 14:56:33 -0700 |
Mine is not so pretty, so let me look at yours. Thanks for taking the time. Mark
Here's a complete version of a "List" template, which also handles iterating through all the present languages, building a table for each.
Keep in mind that using something like "position()" inside of a [predicate] gives the position of the context node being filtered by the predicate. If you want to use the position of the node that is current outside the XPath expression, you generally need to save it to a variable, first, and use that inside the predicate, as shown here.
<xsl:template match="List"> <xsl:for-each-group select="Item" group-by="@lang"> <xsl:variable name="group" select="current-group()"/> <xsl:variable name="rowcount" select="ceiling(count($group) div 3)"/> <table class="motif" lang="{@lang}"> <xsl:for-each select="$group[position() <= $rowcount]"> <xsl:variable name="pos" select="position() - 1"/> <tr> <xsl:apply-templates select="$group[(position() - 1) mod $rowcount = $pos]"/> </tr> </xsl:for-each> </table> </xsl:for-each-group> </xsl:template>
My first problem solved: the round() caused the extra row; did not realize I
had done that when I was trying to get rid of the decimal/integer problem.
Thus, my problem is specifying the entries for the second and third columns,
which I flat out do not understand. Can anyone point out my XPath error,
please? Or is it context? I have not a clue.
For the second column I tried many variation on the following with no success (the full code is below): <xsl:apply-templates select="../Item[@lang eq 'en'][position() + $rowcount]"/> Thanks, Mark
-----Original Message----- From: Mark Sent: Sunday, September 18, 2011 12:35 PM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: Re: [xsl] Changing table output from horizontal to vertical
Hi Liam,
Thanks for the code. I have a few problems. I am using XSLT2. First, I could
not specify the variable as="xs:integer"; the processor complained about the
raw value being a decimal. Second, the code gives me 10 rows, not 9, because
I am rounding up: this means I will have unnecessary blank cells. I know
that changing the +2 to a +1 will stop that, but I did not know why the +2
was in the expression in the first place. The most important issue is that I
do not know how to specify the second and third columns. My code (which only
gives me the first column with 10, not 9, cells), looks like this:
<xsl:variable name="rowcount" select="round((count(Item[@lang eq 'en']) + 2)
div 3)"/>
<table class="motif" lang="en">
<xsl:for-each select="Item[@lang eq 'en'][position()
<=$rowcount]">
<tr>
<xsl:apply-templates select="."/>
<xsl:apply-templates select="../Item[@lang eq
'en'][position() + $rowcount]"/> <!-- Not working at all -->
<xsl:apply-templates select="../Item[@lang eq
'en'][position() + $rowcount + $rowcount]"/> <!-- Not working at all -->
</tr>
</xsl:for-each>
</table>
and the <Item> template:
<xsl:template match="Item">
<td>
<h4>
<xsl:element name="a">
<xsl:attribute name="href" select="@file"/>
<xsl:value-of select="@concept"/>
</xsl:element>
</h4>
</td>
</xsl:template>
Can you help clear this up for me?
-----Original Message----- From: Liam R E Quin Sent: Sunday, September 18, 2011 10:16 AM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: Re: [xsl] Changing table output from horizontal to vertical
On Sun, 2011-09-18 at 09:50 -0700, Mark wrote:
Hi, I am using an XSLT template to produce an XHTML table.
Currently, the
stylesheet fills the table in a horizontal direction; I would like to fill
the table in a vertical direction.
Instead of thinking of filling a table, think of it as a mapping from the input tree to the output grid... Each output tr will start with the nth input item and then have the n + NRth item, then n + NR * 2, and so on, where NR is the number of rows (rounded up to the nearest integer if there's a partial row).
You can work out the total number of rows (I'd store it in an XSLT variable for clarity) e.g. in the template for List you could do <xsl:template match="List"> <xsl:variable name="rowcount" select="(ncount(Item[@lang eq $langcode]) + 2) div 3" as="xs:integer" /> (if you are still in 1998 and XSLT 1, leave of the "as" attribute and use = instead of eq)
<!--* now you can map the Items to table cells. *--> <xsl:for-each select="Item[@lang eq $langcode][position() <= $rowcount]"> <xsl:apply-templates select="." /> </xsl:for-each> </xsl:template>
In this example $langcode is a global parameter to the stylesheet, but to handle both languages make it a tunnel parameter, or in XSLT 1 make it a literal parameter and add it as an argument to the List template, or if List generates the tables, you could instead do, <xsl:for-each select="distinct-values(Item/@lang)"> generate a table in here </xsl:for-each> perhaps with an xsl:sort instruction in there :)
Liam
-- Liam Quin - XML Activity Lead, W3C, http://www.w3.org/People/Quin/ Pictures from old books: http://fromoldbooks.org/
Current Thread |
---|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Changing table output fro, Brandon Ibach | Thread | Re: [xsl] Changing table output fro, Mark |
Re: [xsl] Changing table output fro, Brandon Ibach | Date | Re: [xsl] Changing table output fro, Mark |
Month |