Сортировка XML по формату даты RFC-822 с использованием XSL

Кто-нибудь знает способ сделать такую ​​​​сортировку в XSL?

Вот что у меня есть до сих пор, но оно сортируется только по дням и игнорирует остальную часть даты.

      <xsl:apply-templates select="item">
          <xsl:sort select="pubDate" data-type="text" order="descending"/>
      </xsl:apply-templates>

person AdamRox    schedule 21.02.2013    source источник
comment
Дата - это просто дата или дата-время? Вы используете XSLT 1.0 или XSLT 2.0? Также вы могли бы отредактировать свой ответ, опубликовав свой XML?   -  person Pablo Pozo    schedule 22.02.2013
comment
Это, конечно, возможно, но не тривиально. Вы должны написать синтаксический анализатор на XSLT, который преобразует даты RFC-822 во что-то сортируемое. Я бы выбрал функции EXSLT и строковые функции XPath.   -  person nwellnhof    schedule 22.02.2013
comment
это может быть полезно codeproject.com/Articles/4261/Sorting-dates- in-XSL   -  person Vinit    schedule 22.02.2013


Ответы (1)


Спасибо за быстрые ответы, ребята. Направил меня в правильном направлении. Удалось решить! Нашел полезную ссылку http://blog.mastykarz.nl/how-to-do-it-rss-aggregation-merging-multiple-xml-files-using-xslt/

Я использовал XSLT версии 2.0. Просто случай, когда используется переменная для замены месяцев MMM и подстроки даты.

РЕШЕНИЕ

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="Months" select="'Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec'"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

<xsl:template match="channel">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()[not(preceding-sibling::item) and not(self::item)]"/>
        <xsl:apply-templates select="item">
            <!-- year -->
        <xsl:sort select="substring(pubDate, 13, 4)" order="descending" data-type="number"/>
        <!-- month -->
        <xsl:sort select="string-length(substring-before($Months, substring(pubDate, 9, 3)))" order="descending" data-type="number"/>
        <!-- day -->
        <xsl:sort select="substring(pubDate, 6, 2)" order="descending" data-type="number"/>
        <!-- hour -->
        <xsl:sort select="substring(pubDate, 18, 2)" order="descending" data-type="number"/>

        </xsl:apply-templates>
        <xsl:apply-templates select="@*|node()[not(following-sibling::item) and not(self::item)]"/>
</xsl:copy>
</xsl:template>

person AdamRox    schedule 22.02.2013
comment
Это решение кажется очень хрупким, поскольку предполагает, что элементы даты и времени всегда находятся в одной и той же позиции в строке. Это не обязательно правда. Например, день недели в начале даты и времени не является обязательным. Кроме того, день месяца может быть указан с помощью одной или двух цифр. - person nwellnhof; 23.02.2013
comment
@nwellnhof Этого не должно быть, если они используют даты RFC-822. Я предполагаю, что OP использует RSS-канал, и для его проверки у pubDate очень строгие требования. Это правда, что pubDate не обязательно должен быть в формате, но он нужен для проверки. - person doubleJ; 07.11.2013