В моей предыдущей заметке я описал, как отобразить RSS-ленту в браузере с использованием XSLT. Но иногда важно не просто вывести, но еще и изменить порядок записей в ленте, например, отсортировать их по дате. XSLT 1.1 позволяет сортировать по сложным типам данных, но, к сожалению, XSLT 1.0 не позволяет, потому необходимо извлечь отдельные части даты.
Для начала я покажу, насколько просто отсортировать по дате в XSLT 1.1. Необходимо объявить пространство имен dc:
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/"> |
Теперь осталось только отсортировать:
1 2 3 | <xsl:apply-templates select="item"> <xsl:sort select="pubDate" data-type="dc:date" order="ascending"/> </xsl:apply-templates> |
Как я сказал ранее, в XSLT 1.0 необходимо разрезать дату, получив день, месяц, год и т.д. Для преобразования месяца в число я буду использовать следующее XML-дерево:
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> |
Настало время написания кода для сортировки:
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> |
Вот и все. Элементы ленты будут отсортированы по дате в порядке возрастания.
Вы можете посмотреть результаты здесь или скачать исходные коды здесь.

интересно, а можно убрать записи с повторяющейся датой?
Может это лучше делать на сервере?
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 [...]