Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
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 February 16th, 2010, 12:56 PM
Friend of Wrox
Points: 1,243, Level: 13
Points: 1,243, Level: 13 Points: 1,243, Level: 13 Points: 1,243, Level: 13
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Oct 2003
Location: , , United Kingdom.
Posts: 290
Thanks: 24
Thanked 0 Times in 0 Posts
Default HARD SORTING FOR ME

Hi,

I am using XSLT 1 and MSXML

I have been trying to sort an xml for hours now but to no avail.

I have decided to use an Identity template so that I can output the same xml except sorted in a different order.

I have to sort based on the Ad/@date attribute. I have tried a couple of sort expressions but they do not sort the xml. I have started from the root of the xml and also using the //.

<xsl:template match="/">
<xsl:apply-templates>
<xsl:sort data-type="text" select="//Ad/Issues/Issues/@date"order="descending"/>
<!--<xsl:sort data-type="text" select="xml/Schedule/Media/Vehicle/RateCards...s/Issues/@date" order="descending"/>-->
</xsl:apply-templates>
</xsl:template>


Each Vehicle key in my xml has a collection of Ads. The @date attribute is inside the Ad/Issues/Issue. So, within my first vehicle key (="AMER_FAMILY_PHYSICIAN) if I have this xml as input:

<Ads>
<Ad key="3152:6261" manufac="">
<RateCardRate value="18280.1" />
<ManualRate value="" AdjustedValue="" />
<Position id="531" name="Cover 4" />
<Issues>
<Issue date="2010-02-01">
<Insertion />
</Issue>
<Issue date="2010-03-01">
<Insertion changed="0" />
</Issue>
</Issues>
</Ad>
<Ad key="3152:6261" manufac="">
<RateCardRate value="11806.5" />
<ManualRate value="" AdjustedValue="" />
<Position id="0" name="" />
<Issues>
<Issue date="2010-03-15">
<Insertion />
</Issue>
</Issues>
</Ad>
</Ads>


I need this outupt for descending and vice versa for ascending:

<Ads>
<Ad key="3152:6261" manufac="">
<RateCardRate value="11806.5" />
<ManualRate value="" AdjustedValue="" />
<Position id="0" name="" />
<Issues>
<Issue date="2010-03-15">
<Insertion />
</Issue>
</Issues>
</Ad>


<Ad key="3152:6261" manufac="">
<RateCardRate value="18280.1" />
<ManualRate value="" AdjustedValue="" />
<Position id="531" name="Cover 4" />
<Issues>
<Issue date="2010-02-01">
<Insertion />
</Issue>
<Issue date="2010-03-01">
<Insertion changed="0" />
</Issue>
</Issues>
</Ad>
</Ads>

I would appreciate your help very much.

Cheers

C



XML
-------

<xml>
<Schedule projectId="2345" name="Con" id="7632" xmlns="">
<Media detail="1">
<Vehicle key="AMER_FAMILY_PHYSICIAN" AgencyDiscount="15" CashDiscount="0" title="American Family Physician" insCount="1">
<RateCards>
<RateCard id="7897" name="2010" detail="1">
<EarnedBW value="1"></EarnedBW>
<EarnedColour value="1"></EarnedColour>
<Ads>
<Ad key="3152:6261" manufac="">
<RateCardRate value="18280.1"></RateCardRate>
<ManualRate value="" AdjustedValue=""></ManualRate>
<Position id="531" name="Cover 4"></Position>
<Issues>
<Issue date="2010-02-01">
<Insertion></Insertion>
</Issue>
<Issue date="2010-03-01">
<Insertion changed="0" freq="0" ad="0" manrate="0" pos="0" rcd="0" rate="0" oldRate="18280.10" grossOldRate="21506.00" ordered="18" orderedBy="40" materialFrom="Materials to follow" issueDate="2010-02-12 11:28:47 AM"></Insertion>
</Issue>
</Issues>
</Ad>
<Ad key="3152:6261" manufac="">
<RateCardRate value="11806.5"></RateCardRate>
<ManualRate value="" AdjustedValue=""></ManualRate>
<Position id="0" name=""></Position>
<Issues>
<Issue date="2010-03-15">
<Insertion></Insertion>
</Issue>
</Issues>
</Ad>
</Ads>
</RateCard>
</RateCards>
</Vehicle>
<Vehicle key="AAOS_NOW" AgencyDiscount="15" CashDiscount="0" title="AAOS Now" insCount="1">
<RateCards>
<RateCard id="7859" name="2010" detail="1">
<EarnedBW value="1"></EarnedBW>
<EarnedColour value="1"></EarnedColour>
<Ads>
<Ad key="3152:6261" manufac="">
<RateCardRate value="5984"></RateCardRate>
<ManualRate value="" AdjustedValue=""></ManualRate>
<Position id="531" name="Cover 4"></Position>
<Issues>
<Issue date="2010-03-01">
<Insertion changed="0" freq="0" ad="0" manrate="0" pos="0" rcd="0" rate="0" oldRate="5984.00" grossOldRate="7040.00" ordered="19" orderedBy="40" materialFrom="Materials to follow" issueDate="2010-02-12 11:28:47 AM"></Insertion>
</Issue>
</Issues>
</Ad>
</Ads>
</RateCard>
</RateCards>
</Vehicle>
</Media>
</Schedule>
</xml>


XSLT
-------

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="no" omit-xml-declaration="yes"/>

<xsl:template match="/">
<xsl:apply-templates>
<xsl:sort data-type="text" select="//Ad/Issues/Issues/@date" order="descending"/>
</xsl:apply-templates>

</xsl:template>


<!--add nothing to the result for these-->
<xsl:template match="@*|node()">
<!--identity for all other nodes-->
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>
Reply With Quote
  #2 (permalink)  
Old February 16th, 2010, 01:04 PM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

The document root node "/" has only one element child, which is the Ads element. The apply-templates processes this child. Sorting a sequence containing only one element is not very useful.

It looks to me as if you want to sort the Issue elements within each issue. So use the standard identity template, and supplement it with

Code:
<xsl:template match="Issues">
  <xsl:copy>
     <xsl:apply-templates select="Issue">
        <xsl:sort select="@date"/>
     </
  </
</
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
Reply With Quote
The Following User Says Thank You to mhkay For This Useful Post:
pallone (February 16th, 2010)
  #3 (permalink)  
Old February 16th, 2010, 01:07 PM
Friend of Wrox
Points: 6,676, Level: 34
Points: 6,676, Level: 34 Points: 6,676, Level: 34 Points: 6,676, Level: 34
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Nov 2007
Location: Germany
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Select the nodes you want to sort with the 'select' attribute of your 'xsl:apply-templates', then with the 'xsl:sort select' expression you only select the sort key of each item selected with the apply-templates.
I am currently not sure whether you want to sort the 'Ad' elements or the 'Issue' elements.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
Reply With Quote
  #4 (permalink)  
Old February 16th, 2010, 02:06 PM
Friend of Wrox
Points: 1,243, Level: 13
Points: 1,243, Level: 13 Points: 1,243, Level: 13 Points: 1,243, Level: 13
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Oct 2003
Location: , , United Kingdom.
Posts: 290
Thanks: 24
Thanked 0 Times in 0 Posts
Default

Hi Michael, Martin,

Thanks a lot for your reply.

I will try the sample code that Micheal provided and let you kwow what happens.

Martin, you are right. I need to sort the Ad by issue date.

Cheers

C
Reply With Quote
  #5 (permalink)  
Old February 16th, 2010, 02:11 PM
Friend of Wrox
Points: 6,676, Level: 34
Points: 6,676, Level: 34 Points: 6,676, Level: 34 Points: 6,676, Level: 34
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Nov 2007
Location: Germany
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

But in your sample an 'Ad' element seems to have more than one 'Issue' descendant element so it is not clear which one you want to choose for sorting.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
Reply With Quote
  #6 (permalink)  
Old February 16th, 2010, 02:19 PM
Friend of Wrox
Points: 1,243, Level: 13
Points: 1,243, Level: 13 Points: 1,243, Level: 13 Points: 1,243, Level: 13
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Oct 2003
Location: , , United Kingdom.
Posts: 290
Thanks: 24
Thanked 0 Times in 0 Posts
Default

Hi,

I tried Michael's code but it sorted the Issue nodes by date. see below:


<Ads>
<Ad key="3152:6261" manufac="">
<RateCardRate value="18280.1" />
<ManualRate value="" AdjustedValue="" />
<Position id="531" name="Cover 4" />
<Issues>
<Issue date="2010-03-01">
<Insertion changed="0" />
</Issue>
<Issue date="2010-02-01">
<Insertion />
</Issue>
</Issues>
</Ad>
<Ad key="3152:6261" manufac="">
<RateCardRate value="11806.5" />
<ManualRate value="" AdjustedValue="" />
<Position id="0" name="" />
<Issues>
<Issue date="2010-03-15">
<Insertion />
</Issue>
</Issues>
</Ad>
</Ads>

What I need is to sort Ad by date.

So the Ad collection within the Ads node need to be sorted by the @date attribute that is in the Issue node.

Is this possible?

Please not that the sorting has be done for the whole xml ( i.e. for each VehicleKey node)

Cheers

C
Reply With Quote
  #7 (permalink)  
Old February 16th, 2010, 02:25 PM
Friend of Wrox
Points: 6,676, Level: 34
Points: 6,676, Level: 34 Points: 6,676, Level: 34 Points: 6,676, Level: 34
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Nov 2007
Location: Germany
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

It is certainly possible but before we suggest the next code sample let's define the requirements: which date do you want to choose if an 'Ad' element has more than one 'Issue' descendant?
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
Reply With Quote
  #8 (permalink)  
Old February 16th, 2010, 02:38 PM
Friend of Wrox
Points: 1,243, Level: 13
Points: 1,243, Level: 13 Points: 1,243, Level: 13 Points: 1,243, Level: 13
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Oct 2003
Location: , , United Kingdom.
Posts: 290
Thanks: 24
Thanked 0 Times in 0 Posts
Default

This code seems to be working with the simple xml sample I posted:

<xsl:template match="Ads">
<xsl:copy>
<xsl:apply-templates select="Ad">
<xsl:sort select="Issues/Issue/@date" order="descending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>

However, I can see Martin's point " which date do you want to choose if an 'Ad' element has more than one 'Issue' descendant? "
Reply With Quote
  #9 (permalink)  
Old February 16th, 2010, 02:39 PM
Friend of Wrox
Points: 6,676, Level: 34
Points: 6,676, Level: 34 Points: 6,676, Level: 34 Points: 6,676, Level: 34
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Nov 2007
Location: Germany
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Here is a code sample that sorts on the 'date' attribute of the first 'Issue' descendant

Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>
  
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="Ads">
    <xsl:copy>
      <xsl:apply-templates select="Ad">
        <xsl:sort select="Issues/Issue/@date"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
Reply With Quote
The Following User Says Thank You to Martin Honnen For This Useful Post:
pallone (February 16th, 2010)
  #10 (permalink)  
Old February 16th, 2010, 02:48 PM
Friend of Wrox
Points: 1,243, Level: 13
Points: 1,243, Level: 13 Points: 1,243, Level: 13 Points: 1,243, Level: 13
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Oct 2003
Location: , , United Kingdom.
Posts: 290
Thanks: 24
Thanked 0 Times in 0 Posts
Default

Hi Martin,

Thanks for the sample code.

I will have to think a bit more about that.

I need to produce a table with the ads in order. So if in August I have insertions for different days then I would like to order that.

Aug 1 Sep 10
Aug 10 Sep 15
Aug 15 Sep 20
Aug 25

Cheers

C
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
Hard coded paths pauliehaha Classic ASP Professional 8 February 6th, 2007 06:48 PM
Hard frames problem johnjohn Classic ASP Databases 0 November 30th, 2004 10:38 AM
Datagrid sorting by non alphabetical sorting? LLAndy VS.NET 2002/2003 1 July 15th, 2004 01:20 AM
Windows the hard way astolpho BOOK: Beginning Visual C++ 6 1 March 1st, 2004 05:32 PM
Doesn't recognize hard drive linuxboy Linux 0 October 31st, 2003 02:39 PM



All times are GMT -4. The time now is 07:30 AM.


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