RE: [xsl] Sorting on two booleans

Subject: RE: [xsl] Sorting on two booleans
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Thu, 26 Feb 2009 18:12:34 -0000
Ah sorry, I missed that subtlety. So the first sort key is @active,
descending, and the second is (active = published), false<true:

<xsl:sort select="number(@active = @published)" data-type="number"/>

(or in XSLT 2.0 you can sort booleans directly, with false<true, giving

<xsl:sort select="@active eq @published" />

Alternatively, you can probably do it with a single sort key:

<xsl:for-each select="project">
  <xsl:sort select="substring('dcab', 2*@active + @published + 1, 1)"/> 

But I haven't tested it and it's a bit obscure for practical use.

Michael Kay
http://www.saxonica.com/

> -----Original Message-----
> From: Joelle Tegwen [mailto:tegwe002@xxxxxxx] 
> Sent: 26 February 2009 17:55
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] Sorting on two booleans
> 
> That gives me
> active, not published
> active, published
> not active, not published
> not active, published
> 
> But I need the last two reversed.
> not active, published
> not active, not published
> 
> Thanks
> Joelle
> 
> Michael Kay wrote:
> >> I've got a document that looks like this:
> >> <projects>
> >>     <project active="1" published="1">stuff</project>
> >>     <project active="1" published="0">stuff</project>
> >>     <project active="0" published="1">stuff</project>
> >>     <project active="0" published="0">stuff</project> </projects
> >>
> >> And I need to be able to sort them (on the fly - it's part of a 
> >> sortable table in html) in this order and the reverse:
> >> active, not published
> >> active, published
> >> not active, published
> >> not active, not published.
> >>     
> >
> > So your major sort key is @active (true<false) and your 
> minor sort key 
> > is @published (false<true).
> >
> > That's
> >
> > <xsl:for-each select...>
> >   <xsl:sort select="@active" data-type="number" order="descending"/>
> >   <xsl:sort select="@published" data-type="published" 
> > order="ascending"/>
> >
> > For the reverse order, flip all the order="" attributes.
> >
> > Michael Kay
> > http://www.saxonica.com/
> >
> >
> >   
> >> I've tried all kinds of ways to sort them to get this to happen 
> >> including brute force:
> >>                     <xsl:for-each select="project">
> >>                         <xsl:sort select="@active=1 and 
> @published=0" 
> >> order="ascending"
> >>                             data-type="number"/>
> >>                         <xsl:sort select="@active=1 and 
> @published=1" 
> >> order="ascending"
> >>                             data-type="number"/>
> >>                         <xsl:sort select="@active=0 and 
> @published=1" 
> >> order="ascending"
> >>                             data-type="number"/>
> >>                         <xsl:sort select="@active=0 and 
> @published=0" 
> >> order="ascending"
> >>                             data-type="number"/>
> >>                         <xsl:copy-of select="."/>
> >>                     </xsl:for-each>
> >>
> >>
> >> Nothing works. It always comes out with at least one in the wrong 
> >> spot.
> >>
> >> Could someone point me in the right direction? Help me understand 
> >> what I'm missing about how sort works?
> >>
> >> Thanks much in advance
> >> Joelle

Current Thread