Sorting RSS-feed by date using XSLT

Posted by Dmytro Shteflyuk on under Development

In my previous post I’ve described how to display RSS-feed in browser using XSLT. But sometimes It’s necessary to change order of items in feed, for example sort them by date. XSLT 1.1 allows sorting by complex data types, but XSLT 1.0 does not and we need extract separate date parts.

First I want to demonstrate simplicity of sorting by date in XSLT 1.1. We need just define dc namespace:

1
2
3
4
<xsl:stylesheet version="1.1"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:digg="http://digg.com//docs/diggrss/"
  xmlns:dc="http://purl.org/dc/elements/1.1/">

Now we are ready to sort:

1
2
3
<xsl:apply-templates select="item">
  <xsl:sort select="pubDate" data-type="dc:date" order="ascending"/>
</xsl:apply-templates>

As I said early in XSLT 1.0 we need to split date to get day, month and so on. To convert month to number I will use following XML-tree:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  <months:months>
    <name>Jan</name>
    <name>Feb</name>
    <name>Mar</name>
    <name>Apr</name>
    <name>May</name>
    <name>Jun</name>
    <name>Jul</name>
    <name>Aug</name>
    <name>Sep</name>
    <name>Oct</name>
    <name>Nov</name>
    <name>Dec</name>
  </months:months>

It’s time to create sorting code:

1
2
3
4
5
6
7
8
9
10
11
<xsl:variable name="vMonths" select="document('')/*/months:*"/>
<xsl:apply-templates select="item">
  <xsl:sort select="substring(substring-after(substring-after(substring-after(pubDate, ' '), ' '), ' '), 1, 4)" order="ascending"/>
  <xsl:sort select="count($vMonths/name[
                  .=substring(substring-after(substring-after(current()/pubDate, ' '), ' '), 1, 3)]
                  /preceding-sibling::name)"

            data-type="number"
            order="ascending"/>
  <xsl:sort select="substring(substring-after(pubDate, ' '), 1, 2)" data-type="number" order="ascending"/>
  <xsl:sort select="substring(substring-after(substring-after(substring-after(substring-after(pubDate, ' '), ' '), ' '), ' '), 1, 8)" data-type="text" order="ascending"/>
</xsl:apply-templates>

That’s all. Feed items will be sorted by date in ascending order.

You can view results here or download full sources here.

Books recommended

11 Responses to this entry

Subscribe to comments with RSS

test
said on September 23rd, 2006 at 17:42 · Permalink

интересно, а можно убрать записи с повторяющейся датой?

said on September 25th, 2006 at 13:44 · Permalink

Может это лучше делать на сервере?

said on October 9th, 2006 at 15:36 · Permalink

Hi, I am slowly developing a website and I wanted to put some RSS feeds into my site to pad out the content. They will update as well which means I don’t have to worry about that.

I was thinking of using XSLT and your article is very interesting. I have two questions:
1. Can I just inlclude the XML file as a PHP include and the page will display the transformed XML as HTML with the rest of the page around it?
2. How can you limit the number of items you bring through. i.e. If you only want the latest story from each feed.

Thanks for any help/advice in advance!

said on October 10th, 2006 at 05:01 · Permalink

Hello, adamr
Thank you for you interest. Of course, you can do all you need using XSLT, but I think this is not so good solution. It will be better to parse XML using native PHP libraries and build result HTML.

1. You can’t do this, but… you have ability to transform XML using XSLT with PHP code, just look at XSLT extension or DOM XML extension. There are many articles in the net about this (just look at Google

2. To show only lastest of strories you can use something like (XSLT 1.1)

1
2
3
4
5
6
<xsl:for-each select="item">
  <xsl:sort select="pubDate" data-type="dc:date" order="ascending"/>
  <xsl:if test="position() = 1">
    <xsl:apply-templates/>
  </xsl:if>
</xsl:for-each>

instead of

1
2
3
<xsl:apply-templates select="item">
  <xsl:sort select="pubDate" data-type="dc:date" order="ascending"/>
</xsl:apply-templates>
said on October 10th, 2006 at 11:08 · Permalink

Hi Kpumuk, thanks for your reply. I have spent a long time searching through Google and I agree that PHP seems to be the easiest way to transform XML into HTML for use in a page. I am already using one called CaRP which works quite well.

In principle though XSLT should be a good way of doing this but perhaps at a higher level than I am trying…..;-)

said on November 25th, 2006 at 14:14 · Permalink

Thanks! This is just what I needed, you saved me a lot of time!

said on June 9th, 2007 at 21:49 · Permalink

А как отсортировать rss средствами xml? Загонять все в массив?

said on June 9th, 2007 at 22:51 · Permalink

Ошибка, не средствами xml, а php.

said on March 16th, 2008 at 20:16 · Permalink

Интересно, а какой у вас плагин подсветки синтаксиса?

Comments are closed

Comments for this entry are closed for a while. If you have anything to say – use a contact form. Thank you for your patience.