Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old August 12th, 2005, 01:41 AM
Registered User
 
Join Date: Aug 2005
Location: , , .
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default Sorting & Limiting a for-each (top most recent)

Hello,

What I am effectively trying to achieve is sorting a group of elements, then from this sorted grouping return the top 5 elements.

Cut down version of the XML is:

Code:
<customfield name="WhatsNew">
    <pages>
        <listitem>
              <title>Wrox books are cool</title> 
              <url>/theforums/aregreat/</url> 
            <doc-dates>
                <published-date>2005-07-29T15:02:52.9800000+10:00</published-date> 
            </doc-dates>
        </listitem>
        <listitem>
              <title>Wrox books are cool</title> 
              <url>/theforums/aregreat/</url> 
            <doc-dates>
                <published-date>2005-08-29T15:02:52.9800000+10:00</published-date> 
            </doc-dates>
        </listitem>
    </pages>
    <sections>
        <listitem>
              <title>Wrox books are cool</title> 
              <url>/theforums/aregreat/</url> 
            <doc-dates>
                <published-date>2005-03-29T15:02:52.9800000+10:00</published-date> 
            </doc-dates>
        </listitem>
    </sections>
<customfield>
A cut down version of what I was trying was:

Code:
<xsl:for-each select="//customfield[@name='WhatsNew']/node()/listitem">
    <xsl:sort select="doc-dates/published-date" order="descending" />
    <xsl:if test="position() &lt; 6">
        <xsl:variable name="day" select="substring(doc-dates/published-date,9,2)" />

        <a>
            <xsl:attribute name="href">
                <xsl:value-of select="url"/>
            </xsl:attribute>
            <xsl:value-of select="title"/> 
        </a> - <xsl:value-of select="$day"/>
    </xsl:if>
</xsl:for-each>
Now from what I can tell "position()" only refers the the position of the element within the XML not within the 'sorted' version of it.

Any suggestions would be much appreciated!!!!

Reply With Quote
  #2 (permalink)  
Old August 12th, 2005, 02:39 AM
mhkay's Avatar
Wrox Author
Points: 18,481, Level: 59
Points: 18,481, Level: 59 Points: 18,481, Level: 59 Points: 18,481, Level: 59
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,960
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Your design approach looks fine. Within a sorted for-each, position() refers to the position in sorted order.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #3 (permalink)  
Old August 13th, 2005, 04:43 AM
joefawcett's Avatar
Wrox Author
Points: 9,763, Level: 42
Points: 9,763, Level: 42 Points: 9,763, Level: 42 Points: 9,763, Level: 42
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Exeter, , United Kingdom.
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

As Michael said it looks fine, perhaps your dates are not all in the same time zone so the sort will not function as planned?

--

Joe (Microsoft MVP - XML)
Reply With Quote
  #4 (permalink)  
Old August 16th, 2005, 12:35 AM
Registered User
 
Join Date: Aug 2005
Location: , , .
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

My apologies, upon testing this again everything work correctly.

I can only assume amongst all of the changes I have been making I made some clumsy version error.

Many thanks!!
Reply With Quote
  #5 (permalink)  
Old October 6th, 2005, 06:31 PM
Registered User
 
Join Date: Oct 2005
Location: , , .
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi there,

I also used sorting to get the maximum values - the top three, to be specific.
But I have two issues:

1. I have to change the commands to also consider negative values - sorting should be done using absolute values.
Is this possible with the sort function? Or do I have to take a different approach?

2. I currently have a sub-optimal approach, as I use the code below six times in a row to create variables holding the top three and the resp. values.

(The important part of) the XML file looks like this:

Code:
<arrayLine Name="abc">
  <arrayField Name="F1">13.491</arrayField>
  <arrayField Name="F2">12.023</arrayField>
  <arrayField Name="F3">1.676</arrayField>
  <arrayField Name="F4">-33.884</arrayField>
  <arrayField Name="F5">11.592</arrayField>
  <arrayField Name="F6">9.291</arrayField>
  <arrayField Name="F7">1.743</arrayField>
</arrayLine>
<arrayLine Name="xyz">
  <arrayField Name="F1">21.433</arrayField>
  <arrayField Name="F2">4.326</arrayField>
  <arrayField Name="F3">12.891</arrayField>
  <arrayField Name="F4">0.150</arrayField>
  <arrayField Name="F5">10.471</arrayField>
  <arrayField Name="F6">23.803</arrayField>
  <arrayField Name="F7">14.555</arrayField>
</arrayLine>
...
I have to get the top three values for a given "Fn" from all arrayLine's and the names of the resp. arrayLine's.
In the example code above, it would be
for F1:
topOne = xyz
topOneValue = 21.433
topTwo = abc
topTwoValue = 13.491

for F4:
topOne = abc
topOneValue = -33.884
topTwo = xyz
topTwoValue = 0.150

The corresponding code snippet for getting topOne:
Code:
<xsl:variable name="topOne">
    <xsl:for-each select="arrayLine/arrayField[@Name=$currentFactor]">
        <xsl:sort data-type="number" order="descending"/>
        <xsl:if test="position()=1">
            <xsl:value-of select="../@Name"/>
        </xsl:if>
        </xsl:for-each>
</xsl:variable>
($currentFactor gets iterated from F1 to F7)

Could you please give me advise how to do this?
Thanks in advance! :)

Cheers,
Dennis

P.S.: Is it possible to only take a fixed number of digits after the decimal point?
Reply With Quote
  #6 (permalink)  
Old October 7th, 2005, 02:59 AM
mhkay's Avatar
Wrox Author
Points: 18,481, Level: 59
Points: 18,481, Level: 59 Points: 18,481, Level: 59 Points: 18,481, Level: 59
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,960
Thanks: 0
Thanked 292 Times in 287 Posts
Default

To sort on absolute numeric value:

In XSLT 2.0 use

<xsl:sort select="abs(XXX)"/>

In XSLT 1.0 use

<xsl:sort select="translate(XXX, '-' '')" data-type="number"/>

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #7 (permalink)  
Old October 8th, 2005, 05:45 PM
Registered User
 
Join Date: Oct 2005
Location: , , .
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:<xsl:sort select="translate(XXX, '-' '')" data-type="number"/>
That did the job. Thanks, Michael!

I didn't know that XSLT 2.0 isn't widely supported so far. :(

Quote:
quote:Now from what I can tell "position()" only refers the the position of the element within the XML not within the 'sorted' version of it.
Actually, it seems to refer to the sorted version for me...

Reply With Quote
  #8 (permalink)  
Old October 8th, 2005, 06:02 PM
mhkay's Avatar
Wrox Author
Points: 18,481, Level: 59
Points: 18,481, Level: 59 Points: 18,481, Level: 59 Points: 18,481, Level: 59
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,960
Thanks: 0
Thanked 292 Times in 287 Posts
Default

As mentioned in my first posting in this thread (dated 08/12/2005 - I think it must mean 12th August), within the body of an xsl:for-each, position() refers to the position in sorted order.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem in Checkbox Combination & sorting method.. akshaymehta007 Classic ASP Professional 0 December 28th, 2007 01:32 AM
SELECT TOP n NOT SELECTING TOP n! ibi SQL Language 8 March 30th, 2005 08:08 PM
Linux & KDE & C++ & QT & MYSQL & Kdevelop Munnnki Linux 0 January 2nd, 2005 05:41 PM
Limiting MySQL data maedhros Beginning PHP 1 August 2nd, 2003 07:00 PM
session details & 2 fields sorting qwprince Classic ASP Databases 2 August 2nd, 2003 05:43 AM



All times are GMT -4. The time now is 01:24 PM.


Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.