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