XSLT: sorting and grouping

C

Christian Ludwig

Hello,

I have the following problem. Suppose you habe an XML File (containing
Bibliography-Data) of the form:

<bib>
<bibentry>
<title>Booktitle 1</title>
<year>1990</year>
<!-- some more elements -->
</bibentry>

<bibentry>
<title>Booktitle 2</title>
<year>1991</year>
<!-- more elements -->
</bibentry>

<!-- etc. -->

</bib>

Now, if I want to show all entries sorted by year, I do something like:

<xsl:for-each select="bib/bibentry">
<xsl:sort select="year" data-type="number" order="ascending" />
<p><xsl:value-of select="year"/>: <xsl:value-of select="title"/></p>
</xsl:for-each>

Now the problem:
How can I add (e.g.) extra space, when a new year starts: If I have 10
Books in the year 1990 and 5 books in the year 1991, I want to place a
special element in the output between the last book of 1990 and the
first book of 1991 in order to have a group per year.

To put it in a more abstract form:
How to implement decisions (conditionals) in the xsl-File, where the
condition depends not only on the current node, but also on the last node?


Can anybody help?

C. Ludwig
 
D

David Andriana

Christian Ludwig said:
How can I add (e.g.) extra space, when a new year starts: If I have 10
Books in the year 1990 and 5 books in the year 1991, I want to place a
special element in the output between the last book of 1990 and the
first book of 1991 in order to have a group per year.

<xsl:template match="/">

<!-- consider all years, one by one, sorted, no double -->
<xsl:for-each select="/bib/bibentry/year
[not(../preceding-sibling::bibentry/year = .)]">
<xsl:sort/>

<xsl:call-template name="handle-year">
<xsl:with-param name="year" select="."/>
</xsl:call-template>

</xsl:for-each>

</xsl:template>


<!-- display all bibentries for a give year -->
<xsl:template name="handle-year">
<xsl:param name="year"/>

<xsl:variable name="bibentries" select="/bib/bibentry[year = $year]"/>

<H1>
Year <xsl:value-of select="$year"/> starts here,
it contains <xsl:value-of select="count($bibentries)"/> books.
</H1>

<xsl:for-each select="$bibentries">
<xsl:value-of select="title"/>
<br/>
</xsl:for-each>

<H1>
Year <xsl:value-of select="$year"/> ends here.
</H1>

</xsl:template>
 
C

Christian Ludwig

<xsl:template match="/">

<!-- consider all years, one by one, sorted, no double -->
<xsl:for-each select="/bib/bibentry/year
[not(../preceding-sibling::bibentry/year = .)]">
<xsl:sort/>

<xsl:call-template name="handle-year">
<xsl:with-param name="year" select="."/>
</xsl:call-template>

</xsl:for-each>

</xsl:template>

Thank you very much, works great.
C. Ludwig
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top