xsl-list
[Top] [All Lists]

Re: [xsl] Sort list by a combination of elements

2006-12-21 06:48:08
Manuel Strehl wrote:
So we have <book>s with <author> elements and <book>s with a
<belongs_to> referring to a series of some author.

Problem: Sort the list of books by the author.

<xsl:sort select="concat( //book/author, //series[ @id =
current()/belongs_to/@ref ]/author )" />. This works, BUT it "feels like
a hack", if you know, what I mean.

I would prefer a more XSLT-like solution, that determines, if there is
an <author> element, sorts by this and uses the <series> author as a
fallback. Does anyone know, if and how this could be done? Schematically:

Hi Manuel,

I'm not sure if you are using XSLT 1.0 or 2.0. Considering you are using 1.0, your approach is not wrong. However, it is easier to write the same without the concat() function. You have several options with sort:

1) applying multiple sorts will sort with the first first, than the next etc (i.e., first sort on author, than by name) 2) use the | operator for doing what you wanted: if X not there, sort by Y: " X | Y "
3) combine (1) and (2)
4) user other xpath functions, such as xpath or keys to create more elaborate sorts.

Here's the sort with:
a) by author, which can come from <series> or <book>
b) by title (all authors together, than title)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
   <xsl:output method="text" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
       <xsl:for-each select="*/book">
           <xsl:sort select="author | //series[ @id =
               current()/belongs_to/@ref ]/author"/>
<xsl:sort select="title" /> <xsl:value-of select="author | //series[ @id =
               current()/belongs_to/@ref ]/author"/>
           <xsl:value-of select="concat(': ', title, '&#xA;')"/>
</xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

I extended the input a bit, and with the following input:
<bookshelf>
   <series id="LoTR">
       <author>Tolkien</author>
   </series>
   <book>
       <title>Two Towers</title>
       <belongs_to ref="LoTR" />
   </book>
   <book>
       <title>The hobbit</title>
       <belongs_to ref="LoTR" />
   </book>
   <book>
       <title>Pygmalion</title>
       <belongs_to ref="LoTR" />
   </book>
   <book>
       <title>It</title>
       <author>King</author>
   </book>
   <book>
       <title>Lisey's story</title>
       <author>King</author>
   </book>
   <book>
       <title>Sociology</title>
       <author>Giddens</author>
   </book>
</bookshelf>

It gives the following result:

Giddens: Sociology
King: It
King: Lisey's story
Tolkien: Pygmalion
Tolkien: The hobbit
Tolkien: Two Towers

Cheers,
-- Abel Braaksma
www.nuntia.nl

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>