gruff
gruff

Reputation: 411

XSL Iterate through list of items

I have an rss feed which is pulling from an abandoned 'Joke of the day' blog. Because the blog is no longer updating, I want to iterate through the list and display a different item each day, ideally in chronological order.

How do I identify the 'first' item in the list (the oldest post) and then show the next item each day?

The rss source is here: http://feeds.feedburner.com/DailyJokes-ACleanJokeEveryday?format=xml The full list is here: http://dailyjokes.somelifeblog.com/

My XSL code is here, and currently displays the item at position 2, which is the most recent post:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
  <xsl:template match="/">
    <xsl:apply-templates select="//item[position() &lt; 2]"/>
  </xsl:template>

  <xsl:template match="item">
    <content-item>
      <h1><xsl:value-of select="substring-before(title, ' #Joke')"/></h1>     
      <p><xsl:value-of select="substring-before(description, '&lt;a href')" disable-output-escaping="yes"/></p>
    </content-item>
  </xsl:template>
</xsl:stylesheet>

I am surfacing this feed in a SharePoint 2013 RSS webpart

My goal is to display a different item each day but I might settle for simple randomization. Also if anybody can suggest a free or for-cost 'Joke of the day' site which is appropriate for my work intranet, that would be appreciated!

Upvotes: 1

Views: 2556

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117102

My goal is to display a different item each day

To accomplish your goal, your processor needs to know the current date.

The following is a minimized example showing how to use the date in order to retrieve a different item every day:

XML

<rss>
    <channel>
        <item>
            <title>Alpha</title>
        </item>
        <item>
            <title>Bravo</title>
        </item>
        <item>
            <title>Charlie</title>
        </item>
        <item>
            <title>Delta</title>
        </item>
        <item>
            <title>Echo</title>
        </item>
    </channel>
</rss>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="current-datetime">2017-04-27T00:00:00</xsl:param>

<xsl:template match="/rss">
    <xsl:variable name="JDN">
        <xsl:call-template name="JDN">
            <xsl:with-param name="date" select="$current-datetime"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="n" select="count(channel/item)" />
    <output>
        <xsl:apply-templates select="channel/item[$JDN mod $n + 1]"/>
    </output>
</xsl:template>

<xsl:template match="item">
    <item>
        <xsl:value-of select="title"/>
    </item>     
</xsl:template>

<xsl:template name="JDN">
    <xsl:param name="date"/>
    <xsl:param name="year" select="substring($date, 1, 4)"/>
    <xsl:param name="month" select="substring($date, 6, 2)"/>
    <xsl:param name="day" select="substring($date, 9, 2)"/>
    <xsl:param name="a" select="floor((14 - $month) div 12)"/>
    <xsl:param name="y" select="$year + 4800 - $a"/>
    <xsl:param name="m" select="$month + 12*$a - 3"/>
    <xsl:value-of select="$day + floor((153*$m + 2) div 5) + 365*$y + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045" />
</xsl:template> 

</xsl:stylesheet>

In this example, the result will be:

<?xml version="1.0" encoding="UTF-8"?>
<output>
  <item>Bravo</item>
</output>

Live demo: http://xsltransform.net/pNmBxZK


If your processor supports the EXSLT date:date-time()extension function, you can modify your stylesheet's header to:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times"
extension-element-prefixes="date">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="current-datetime" select="date:date-time()"/>

For SharePoint, I am guessing you would need to use the TodayIso function in the ddwrt namespace instead.

Upvotes: 1

Related Questions