|
[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: How to get a "heading" from an element
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
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|

Cart








