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.
интересно, а можно убрать записи с повторяющейся датой?
Может это лучше делать на сервере?
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!
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)
2
3
4
5
6
<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
2
3
<xsl:sort select="pubDate" data-type="dc:date" order="ascending"/>
</xsl:apply-templates>
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…..;-)
Thanks! This is just what I needed, you saved me a lot of time!
А как отсортировать rss средствами xml? Загонять все в массив?
Ошибка, не средствами xml, а php.
Интересно, а какой у вас плагин подсветки синтаксиса?
Плагин для подсветки синтаксиса — CodeColorer.
[…] I just found this very useful posting on how to sort RSS feeds by date using XSLT. Read it here […]