RE: [xsl] sorting a table based on first column which contains both numbers and words

Subject: RE: [xsl] sorting a table based on first column which contains both numbers and words
From: "Robby Pelssers" <robby.pelssers@xxxxxxxxx>
Date: Fri, 18 Dec 2009 14:33:17 +0100
Ok...

I created a more usefull table this time to really show what I want:

<?xml version="1.0" encoding="UTF-8"?>
<table>
  <tr>
    <td>5</td>
  </tr>
  <tr>
    <td>111</td>
  </tr>
  <tr>
    <td>3</td>
  </tr>
  <tr>
    <td>Banana</td>
  </tr>
  <tr>
    <td>12</td>
  </tr>
  <tr>
    <td>Apple</td>
  </tr>
</table>

Using 2 sort keys like below
  <xsl:template match="table">
    <table>
      <xsl:apply-templates select="tr">
        <xsl:sort select="td" data-type="number"/>
        <xsl:sort select="td" data-type="text"/>
      </xsl:apply-templates>
    </table>
  </xsl:template>
Results in

<?xml version="1.0" encoding="UTF-8"?>
<table>
  <tr>
    <td>Apple</td>
  </tr>
  <tr>
    <td>Banana</td>
  </tr>
  <tr>
    <td>3</td>
  </tr>
  <tr>
    <td>5</td>
  </tr>
  <tr>
    <td>12</td>
  </tr>
  <tr>
    <td>111</td>
  </tr>
</table>

But I wanted numbers first and then strings.

So uptill now I still see my solution (see below) as the only correct one?
Unless you have yet another idea ;-)

Robby Pelssers

-----Original Message-----
From: Michael Kay [mailto:mike@xxxxxxxxxxxx]
Sent: Thursday, December 17, 2009 5:31 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: RE: [xsl] sorting a table based on first column which contains both
numbers and words

But the default sort will put 10 before 2. If you don't want that you could
do

<xsl:sort select="td" data-type="number"/>
<xsl:sort select="td" data-type="text"/>

i.e. two apparently separate sort keys - if they aren't distinguishable as
numbers (both convert to NaN) then they will be sorted as strings.

Regards,

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

> -----Original Message-----
> From: Robby Pelssers [mailto:robby.pelssers@xxxxxxxxx]
> Sent: 17 December 2009 15:53
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: RE: [xsl] sorting a table based on first column
> which contains both numbers and words
>
> Mm... damn.... I thought I needed to specify the data-type ;-(
>
> So I just came up with following solution:
>
>   <xsl:template match="table">
>     <table>
>       <xsl:variable name="numericRows"
> select="tr[string(number(td)) !='NaN']"/>
>       <xsl:variable name="alphabeticRows"
> select="tr[string(number(td))='NaN']"/>
>       <xsl:apply-templates select="$numericRows">
>         <xsl:sort select="td" data-type="number"/>
>       </xsl:apply-templates>
>       <xsl:apply-templates select="$alphabeticRows">
>         <xsl:sort select="td" data-type="text"/>
>       </xsl:apply-templates>
>     </table>
>   </xsl:template>
>
> But I also tested without specifying any data-type and you're
> right ...aaargh..
>
>   <xsl:template match="table">
>     <table>
>       <xsl:apply-templates select="tr">
>         <xsl:sort select="td"/>
>       </xsl:apply-templates>
>     </table>
>   </xsl:template>
>
> Thx,
> You made life a lot easier ;-)
>
> Robby
>
> -----Original Message-----
> From: Andrew Welch [mailto:andrew.j.welch@xxxxxxxxx]
> Sent: Thursday, December 17, 2009 4:28 PM
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] sorting a table based on first column
> which contains both numbers and words
>
> 2009/12/17 Robby Pelssers <robby.pelssers@xxxxxxxxx>:
> > Hi all,
> >
> > I have the use case where I need to sort a table based on
> it's first column.  This column can contain only numbers but
> also a mix of words and numbers. See example below.
> >
> > <table>
> >   <tr>
> >     <td>5</td>
> >   </tr>
> >   <tr>
> >     <td>3</td>
> >   </tr>
> >   <tr>
> >     <td>Banana</td>
> >   </tr>
> >   <tr>
> >     <td>Apple</td>
> >   </tr>
> > </table>
> >
> >
> > I want following output (first sorted numerical  and then
> > alphabetically)
> >
> > <table>
> >   <tr>
> >     <td>3</td>
> >   </tr>
> >   <tr>
> >     <td>5</td>
> >   </tr>
> >   <tr>
> >     <td>Apple</td>
> >   </tr>
> >   <tr>
> >     <td>Banana</td>
> >   </tr>
> > </table>
> >
> > How can I accomplish this with xslt?
>
>
> The default sort will do that, read about xsl:sort
>
>
> --
> Andrew Welch
> http://andrewjwelch.com
> Kernow: http://kernowforsaxon.sf.net/

Current Thread