XSLT - Группировка элементов по дате - PullRequest
1 голос
/ 26 апреля 2011

То, что я пытаюсь сделать, это отобразить список всех постов блога из файла XML, который содержит список всех заголовков постов блога и даты их публикации.Тип вывода, который я ищу:

Вывод HTML:

<ul>
  <h3>February 2011</h3>
  <li>Blog Title - 09/02/2011</li>
  <li>1 More Blog Title - 19/02/2011</li>
  <h3>March 2011</h3>
  <li>More Blogging - 15/03/2011</li>
  <h3>April 2011</h3>
  <li>Another Title - 29/04/2011</li> 
</ul>

Из следующего XMLL

XML:

<BlogPosts>
  <Post>
    <Title>Blog Title</Title>
    <CreatedBy>A Another</CreatedBy>
    <PublishedDate>09/02/2011</PublishedDate>
    <Url>Http://url.com</Url>
    <BlogBody>Some text here...<BlogBody>
  </Post>
  <Post>
    <Title>1 More Blog Title</Title>
    <CreatedBy>A Another</CreatedBy>
    <PublishedDate>19/02/2011</PublishedDate>
    <Url>Http://url.com</Url>
    <BlogBody>Some text here...<BlogBody>
  </Post>
  <Post>
    <Title>More Blogging</Title>
    <CreatedBy>A Another</CreatedBy>
    <PublishedDate>15/03/2011</PublishedDate>
    <Url>Http://url.com</Url>
    <BlogBody>Some text here...<BlogBody>
  </Post>
  <Post>
    <Title>Another Title</Title>
    <CreatedBy>A Another</CreatedBy>
    <PublishedDate>29/04/2011</PublishedDate>
    <Url>Http://url.com</Url>
    <BlogBody>Some text here...<BlogBody>
  </Post>
</BlogPosts>

Есть ликаким образом я могу сгруппировать BlogPosts по дате, а также вывести название месяца, с которого они используют XSLT?

1 Ответ

1 голос
/ 26 апреля 2011

Эта таблица стилей дает желаемый результат:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:ns="my:ns">
    <xsl:key name="byMonthYear" match="BlogPosts/Post"
        use="substring-after(PublishedDate, '/')" />
    <ns:months>
        <m id="01">January</m>
        <m id="02">February</m>
        <m id="03">March</m>
        <m id="04">April</m>
        <m id="05">May</m>
        <m id="06">June</m>
        <m id="07">July</m>
        <m id="08">August</m>
        <m id="09">September</m>
        <m id="10">October</m>
        <m id="11">November</m>
        <m id="12">December</m>
    </ns:months>
    <xsl:variable name="months" select="document('')/*/ns:months/*" />
    <xsl:template match="/">
        <ul><xsl:apply-templates /></ul>
    </xsl:template>
    <xsl:template match="BlogPosts/Post" />
    <xsl:template
        match="BlogPosts/Post[generate-id()=generate-id(key('byMonthYear', 
                    substring-after(PublishedDate, '/'))[1])]">
        <xsl:variable name="year"
            select="substring-after(
                        substring-after(PublishedDate, '/'), '/')" />
        <xsl:variable name="month"
            select="substring-before(
                        substring-after(PublishedDate, '/'), '/')" />
        <xsl:variable name="monthName" select="$months[@id=$month]" />
        <h3>
            <xsl:value-of select="concat($monthName, ' ', $year)" />
        </h3>
        <xsl:apply-templates
            select="key('byMonthYear', substring-after(PublishedDate, '/'))"
            mode="titles" />
    </xsl:template>
    <xsl:template match="BlogPosts/Post" mode="titles">
        <li>
            <xsl:value-of select="concat(Title, ' - ', PublishedDate)" />
        </li>
    </xsl:template>
</xsl:stylesheet>

Мы группируем по месяцам и годам и используем справочную таблицу для перевода цифр месяца в соответствующее имя. Обратите внимание на использование substring-before и substring-after для анализа даты.

В примечании к педантику списки HTML не могут содержать элементы, отличные от <li>, поэтому желаемый вывод не является допустимым HTML.

...