|
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 |