XML Editor
Sign up for a WebBoard account Sign Up Keyword Search Search More Options... Options
Chat Rooms Chat Help Help News News Log in to WebBoard Log in Not Logged in
Show tree view Topic
Go to previous topicPrev TopicGo to next topicNext Topic
Postnext
Brian BSubject: Need Help Resorting
Author: Brian B
Date: 06 Jul 2005 08:42 AM
I have a xsl sheet that gets 21 records sorted descending by date.
What i'm looking to do is after the 21 records resort by title without
out changing the 21 records, tables, rows, and column layout.

<xsl:template match="rss">
<table border="0" cellspacing="0" width="700">
<tr>
<xsl:for-each select="item">
<xsl:sort select="substring(date, 9)" data-type ="number" order="descending"/>
<xsl:sort select="month" data-type ="number" order="descending"/>
<xsl:sort select="substring(date, 5, 3)" data-type ="number" order="descending"/>
<xsl:if test="position() &lt; 22">
<xsl:if test="position() = 4"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:if test="position() = 7"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:if test="position() = 10"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:if test="position() = 13"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:if test="position() = 16"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:if test="position() = 19"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:call-template name="item">
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</tr>
</table>
</xsl:template>
<xsl:template name="newrow">
<tr>
</tr>
</xsl:template>
<xsl:template name="item">
<td width="228" height="194" class="photoTD" id="tableframe" MCFocusable="true">
<table height="140" cellSpacing="0" cellPadding="0" width="100" border="0">
<span class="btnMedia_nofocus">
<tr>
<td vAlign="center" align="middle"><xsl:value-of select="image" disable-output-escaping="yes"/> </td>
</tr>
</span>
</table>
<div class="text3">
<nobr><xsl:value-of select="title"/></nobr></div>
</td>
<td height="20"></td>
</xsl:template>

</xsl:stylesheet>

Thanks

Postnext
Ivan PedruzziSubject: Need Help Resorting
Author: Ivan Pedruzzi
Date: 06 Jul 2005 12:28 PM

Brian,

Which version fo RSS feed are you using as input?
Isn't the feed already sorted by date?

Are you asking to change the XSLT to sort by title or
would like to have an HTML table that let the the user sort?

Few suggestions to improve the posted XSLT

remove
<xsl:if test="position() &lt; 22">

change the for-each to use a predicate
<xsl:for-each select="//item[position() &lt; 22]">

The following code seems a waste

<xsl:if test="position() = 4"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:if test="position() = 7"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:if test="position() = 10"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:if test="position() = 13"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:if test="position() = 16"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>
<xsl:if test="position() = 19"><xsl:call-template name="newrow"></xsl:call-template></xsl:if>

use the mod operator instead
<xsl:if test="position() mod 3 = 1">
<tr/>
</xsl:if>


Hope this helps
Ivan Pedruzzi
Stylus Studio team

Postnext
Brian BSubject: Need Help Resorting
Author: Brian B
Date: 06 Jul 2005 01:10 PM
The rss feed gets filled with a screen scrape I made. When the xml file is complete it has about 200 records in order by title. I would like get 21 records sorted by date descending first then resort the same 21 records by title in the XSL file.

Thanks

Postnext
Ivan PedruzziSubject: Need Help Resorting
Author: Ivan Pedruzzi
Date: 06 Jul 2005 05:40 PM

Brian, could you please post a sample of your XML input

Thank You
Ivan Pedruzzi
Stylus Studio Team

Postnext
Brian BSubject: Need Help Resorting
Author: Brian B
Date: 06 Jul 2005 06:15 PM
The way my XSL file is now I get the First Results. I want First Results then Second Results.
Also the reason I didn't use
<xsl:if test="position() mod 3 = 1">
and
<xsl:for-each select="//item[position() &lt; 22]">
it only sorts the first 21 records by date. It doesn't go thur all the records then sort.

Here's a sample

First Results
title - date
B ----- Jul 3, 2002
A ----- Jun 19, 2002
C ----- Jan 16, 2002


Second Results
title - date
A ----- Jun 19, 2002
B ----- Jul 3, 2002
C ----- Jan 16, 2002


<?xml version="1.0"?>
<?xml:stylesheet type="text/xsl" href="test.xsl"?>
<rss>
<item>
<title>A</title>
<description>something</description>
<image>JPG</image>
<month>7</month>
<date> Jun 19, 2002 </date>
<link>a href</link>
</item>
<item>
<title>B</title>
<description>something</description>
<image>JPG</image>
<month>8</month>
<date> Jul 3, 2002 </date>
<link>a href</link>
</item>
<item>
<title>C</title>
<description>something</description>
<image>JPG</image>
<month>1</month>
<date> Jan 16, 2002 </date>
<link>a href</link>
</item>
</rss>
This rss file goes down to 200 records in order by title

Thanks

Postnext
Ivan PedruzziSubject: Need Help Resorting
Author: Ivan Pedruzzi
Date: 06 Jul 2005 10:07 PM
Brian,
Try the following solution and see if meets your requirements

Hope this helps
Ivan Pedruzzi
Stylus Studio Team


<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:param name="MaxItems" select="21"/>
<xsl:param name="Columns" select="3"/>

<xsl:template match="/">
<html>
<body>

<xsl:variable name="ItemsByDate">
<xsl:for-each select="rss">
<xsl:copy>
<xsl:for-each select="item">
<!-- format a string to be used a sorting key: yyyy-mm-dd -->
<xsl:sort order="descending" select="concat( substring(substring-after(date, ', '), 1), '-', format-number(month, '00'), '-', format-number(substring(date, 4,2), '00'))"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:variable>

<xsl:variable name="ItemsByTitle">
<xsl:for-each select="rss">
<xsl:copy>
<xsl:for-each select="item">
<xsl:sort order="ascending" select="title"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:variable>

<a><strong>Order by date</strong></a>
<xsl:apply-templates select="$ItemsByDate/rss"/>
<a><strong>Order by title</strong></a>
<xsl:apply-templates select="$ItemsByTitle/rss"/>
</body>
</html>
</xsl:template>

<xsl:template match="rss">
<table border="1" cellspacing="0" width="700">
<tr>
<xsl:for-each select="item">

<!--
position() returns the position in the document order

-->


<xsl:if test="position() &lt;= $MaxItems">
<xsl:if test="position() mod $Columns = 1">
<tr/>
</xsl:if>
<xsl:apply-templates select="."/>
</xsl:if>
</xsl:for-each>
</tr>
</table>
</xsl:template>

<xsl:template match="item">
<td width="228" height="194" class="photoTD" id="tableframe" MCFocusable="true">
<table height="140" cellSpacing="0" cellPadding="0" width="100" border="0">
<span class="btnMedia_nofocus">
<tr>
<td vAlign="center" align="middle">
<xsl:value-of select="image" disable-output-escaping="yes"/>
</td>
</tr>
</span>
</table>
<div class="text3">
<nobr>
<xsl:value-of select="title"/>
<br/>
<xsl:value-of select="date"/>
</nobr>
</div>
</td>
<td height="20"></td>
</xsl:template>
</xsl:stylesheet>

Postnext
Brian BSubject: Need Help Resorting
Author: Brian B
Date: 06 Jul 2005 10:19 PM
It look like what I want but I get an error saying

Reference to variable or parameter 'ItemsByDate' must evaluate to a node list.

I just want to say your setup looks very professional.

Thanks

Postnext
Ivan PedruzziSubject: Need Help Resorting
Author: Ivan Pedruzzi
Date: 06 Jul 2005 10:31 PM
I guess you are using MSXML so you have to change the following

1) declare the Microsoft extension function namespace

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt">

2) use the node-set function

<a><strong>Order by date</strong></a>
<xsl:apply-templates select="msxml:node-set($ItemsByDate)/rss"/>
<a><strong>Order by title</strong></a>
<xsl:apply-templates select="msxml:node-set($ItemsByTitle)/rss"/>


Ivan Pedruzzi
Stylus Studio Team

Postnext
Brian BSubject: Need Help Resorting
Author: Brian B
Date: 06 Jul 2005 11:15 PM
That fixed the error but i'm sorry that not what I wanted. The way you have it I get 21 records showing in order by date then I get 21 records showing in order by title. I only want to see the records order by title but it needs to be the same records as ordered by date.
Example say if I wanted 5 records out of 10

Here's the 10 records in my xml file already ordered by title.
title --- date
A ------- 1/16/2005
B ------- 3/7/2005
C ------- 8/27/2005
D ------- 4/22/2005
E ------- 9/12/2005
F ------- 2/28/2005
G ------- 11/4/2005
H ------- 6/5/2005
I ------- 12/25/2005
J ------- 5/22/2005

If I take 5 records in order by title I get
title --- date
A ------- 1/16/2005
B ------- 3/7/2005
C ------- 8/27/2005
D ------- 4/22/2005
E ------- 9/12/2005
If I take 5 records in order by descending date I get
title --- date
I ------- 12/25/2005
G ------- 11/4/2005
E ------- 9/12/2005
C ------- 8/27/2005
H ------- 6/5/2005

The only thing I want to see is the records order by descending date but resorted by title.

Final Result
title --- date
C ------- 8/27/2005
E ------- 9/12/2005
G ------- 11/4/2005
H ------- 6/5/2005
I ------- 12/25/2005

If this is too much I appreciate what you have done.

Thanks

Postnext
Ivan PedruzziSubject: Need Help Resorting
Author: Ivan Pedruzzi
Date: 07 Jul 2005 01:12 AM

we are getting closer :)

Ivan


<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt">
<xsl:output method="html"/>

<xsl:param name="MaxItems" select="21"/>
<xsl:param name="Columns" select="3"/>

<xsl:template match="/">
<html>
<body>

<xsl:variable name="ItemsByDate">
<xsl:for-each select="rss">
<xsl:copy>
<xsl:for-each select="item">
<!-- format a string to be used a sorting key: yyyy-mm-dd -->
<xsl:sort order="descending" select="concat( substring(substring-after(date, ', '), 1), '-', format-number(month, '00'), '-', format-number(substring(substring-before(date, ', '), 4,3), '00'))"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:variable>

<xsl:variable name="ItemsByDateShort">
<xsl:for-each select="msxml:node-set($ItemsByDate)/rss">
<xsl:copy> <!-- limit to the first MaxItems -->
<xsl:for-each select="item[position() &lt;= $MaxItems]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:variable>

<xsl:variable name="ItemsByTitleShort">
<xsl:for-each select="msxml:node-set($ItemsByDateShort)/rss">
<xsl:copy>
<xsl:for-each select="item">
<xsl:sort order="ascending" select="title"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:variable>

<a><strong>Order by date</strong></a>
<xsl:apply-templates select="msxml:node-set($ItemsByDateShort)/rss"/>
<a><strong>Order by title</strong></a>
<xsl:apply-templates select="msxml:node-set($ItemsByTitleShort)/rss"/>
</body>
</html>
</xsl:template>

<xsl:template match="rss">
<table border="1" cellspacing="0" width="700">
<tr>
<xsl:for-each select="item">
<xsl:if test="position() mod $Columns = 1">
<tr/>
</xsl:if>
<xsl:apply-templates select="."/>
</xsl:for-each>
</tr>
</table>
</xsl:template>

<xsl:template match="item">
<td width="228" height="194" class="photoTD" id="tableframe" MCFocusable="true">
<table height="140" cellSpacing="0" cellPadding="0" width="100" border="0">
<span class="btnMedia_nofocus">
<tr>
<td vAlign="center" align="middle">
<xsl:value-of select="image" disable-output-escaping="yes"/>
</td>
</tr>
</span>
</table>
<div class="text3">
<nobr>
<xsl:value-of select="title"/>
<br/>
<xsl:value-of select="date"/>
</nobr>
</div>
</td>
<td height="20"></td>
</xsl:template>
</xsl:stylesheet>

Posttop
Brian BSubject: Need Help Resorting
Author: Brian B
Date: 07 Jul 2005 10:05 AM
WOW thats exactly what I wanted. I'm new to XSLT and I figured it would have something to do with <xsl:copy>. Ivan you are the best.

Thanks again.

 
Go to previous topicPrev TopicGo to next topicNext Topic
Download A Free Trial of Stylus Studio 6 XML Professional Edition Today! Powered by Stylus Studio, the world's leading XML IDE for XML, XSLT, XQuery, XML Schema, DTD, XPath, WSDL, XHTML, SQL/XML, and XML Mapping!  
go

Log In Options

Site Map | Privacy Policy | Terms of Use | Trademarks
Stylus Scoop XML Newsletter:
W3C Member
Stylus Studio® and DataDirect XQuery ™are from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2016 All Rights Reserved.