Subject: Re: [xsl] How to get a "heading" from an element From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Sat, 9 Feb 2002 12:52:40 +0000 |
Hi Roger, > I'm having a real problem with something apparently simple. This is a grouping problem. You want to group the airline elements in your source document into groups according to their airline-name. >From the looks of it, the airline elements are listed in order, and the kind of grouping that you want to do just involves adding a header at the top of each group. That means you can use something quite simple to do the grouping. Iterate over the airline elements one by one; I'd apply templates to them as follows: <xsl:apply-templates select="airline" /> Then have a template that matches airline elements: <xsl:template match="airline"> ... </xsl:template> But of course you could use an xsl:for-each instead if you're more comfortable with it. For each airline element, you want to create a row that contains a cell for the airport-code and a cell for the airport-name, as follows: <tr> <td><xsl:value-of select="airport-code" /></td> <td><xsl:value-of select="airport-name" /></td> </tr> Then for certain airline elements, you want to add a header before this row. The airline elements where you need to add a header are those that are the first with a particular airline-name. Given that your file is sorted, you can tell which are first with a particular airline-name by looking at their immediately preceding sibling airline (if they have one). If the airline-name of the immediately preceding sibling airline is different from the airline-name of this airline, then it's the first in a group. You can get the immediately preceding sibling airline with: preceding-sibling::airline[1] You can compare its airline-name with this airline's airline-name with: preceding-sibling::airline[1]/airline-name != airline-name And you can use an xsl:if to decide, on the basis of this test, whether to add the header or not. So the content of the xsl:template or xsl:for-each would be: <xsl:if test="preceding-sibling::airline[1]/airline-name != airline-name"> <tr> <td><xsl:value-of select="airline-name" /></td> </tr> </xsl:if> <tr> <td><xsl:value-of select="airport-code" /></td> <td><xsl:value-of select="airport-name" /></td> </tr> Note that this only works because your airline elements are already sorted by airline-name. If they were not sorted, you'd need to use a more sophisticated grouping method, such as Muenchian grouping (see http://www.jenitennison.com/xslt/grouping/muenchian.html). --- For interest, the XSLT 2.0 method would be: <xsl:for-each-group select="airline" group-by="airline-name"> <tr> <td><xsl:value-of select="airline-name" /></td> </tr> <xsl:for-each select="current-group()"> <tr> <td><xsl:value-of select="airport-code" /></td> <td><xsl:value-of select="airport-name" /></td> </tr> </xsl:for-each> </xsl:for-each-group> Or, alternatively, since you're dealing with an ordered list of airlines: <xsl:for-each-group select="airline" group-adjacent="airline-name"> <tr> <td><xsl:value-of select="airline-name" /></td> </tr> <xsl:for-each select="current-group()"> <tr> <td><xsl:value-of select="airport-code" /></td> <td><xsl:value-of select="airport-name" /></td> </tr> </xsl:for-each> </xsl:for-each-group> I hope that helps, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] How to get a "heading" from a, Roger Chung-Wee | Thread | Re: [xsl] How to get a "heading" fr, Roger Chung-Wee |
Re: [xsl] Sorting Problem, Jeni Tennison | Date | Re: [xsl] Variable scope issue., Jeni Tennison |
Month |