Subject: [xsl] Grouping By Column Heading (by Position, not by ID or element name) From: "G. T. Stresen-Reuter" <tedmasterweb@xxxxxxxxx> Date: Tue, 29 Apr 2014 15:50:18 +0100 |
Hi, I regularly find myself having to transform tables in XHTML. The data is frequently organized by column headings. This seems like an obvious opportunity for grouping using Keys, and I've gotten it to work, but I'm having trouble understanding *why* it's working. Please note that this is not the typical grouping example where an attribute or element name identifies what group something belongs to but rather an example in which an elements *position* relative to other elements is what defines the group. Given: <table> <tr> <td>Fruits</td> <td>Veggies</td> <td>Lactose</td> </tr> <tr> <td>Apples</td> <td>Carrots</td> <td>Milk</td> </tr> <tr> <td>Bananas</td> <td>Peas</td> <td>Cheese</td> </tr> <tr> <td>Plums</td> <td>Celery</td> <td>Eggs</td> </tr> </table> I want to end up with: <foods> <foodGroup name="Fruits"> <food>Apples</food> <food>Bananas</food> <food>Plums</food> </foodGroup> <foodGroup name="Veggies"> <food>Carrots</food> <food>Peas</food> <food>Celery</food> </foodGroup> <foodGroup name="Lactose"> <food>Milk</food> <food>Cheese</food> <food>Eggs</food> </foodGroup> </foods> I've found that the following XSLT works, but I don't understand why and I suspect that I am just getting lucky or that the Key element could be better written (optimized?). I would be very grateful if someone with more experience at this than I could take a look at this XSLT and explain: 1) How is a TD element (found in the USE attribute of my Key) able to act as unique identifier for a TR element (it's parent)? 2) How should this be done (assuming mine is not optimal)? Please note that I realize this does not require using keys (I don't think) but I like using keys because it makes sense semantically. Here's the XSLT and thanks in advance. <xsl:key name="food-group" match="//table/tr[position() > 1]" use="ancestor-or-self::table/tr[position() = 1]/td" /> <xsl:template match="/table"> <xsl:element name="foods"> <xsl:apply-templates select="tr[position() = 1]/td"/> </xsl:element> </xsl:template> <xsl:template match="td"> <xsl:variable name="i" select="position()" /> <xsl:element name="foodGroup"> <xsl:attribute name="name"><xsl:value-of select="." /></xsl:attribute> <xsl:for-each select="key('food-group', .)"> <xsl:element name="food"> <xsl:value-of select="td[position() = $i]" /> </xsl:element> </xsl:for-each> </xsl:element> </xsl:template> Ted Stresen-Reuter
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] What is actually a "fragm, Michael Kay | Thread | Re: [xsl] Grouping By Column Headin, Wendell Piez |
Re: [xsl] dangling attribute creati, Ihe Onwuka | Date | [xsl] Changes to the List Software, Tommie Usdin |
Month |