Home > Blogs > Eric Shupps | The SharePoint Cowboy > Posts > SharePoint 2007 RSS Aggregation Web Part
 
​The SharePoint Cowboy


photo of Eric Shupps
BinaryWave
611 S. Main St., Suite 400
Grapevine , TX , 76051 USA
May 03
SharePoint 2007 RSS Aggregation Web Part
One of the most common requirements we have these days is to display RSS feeds on WSS/MOSS sites inside of a web part.  Most users want the ability to see just a list of article links, sorted by date, from multiple feed sources - a collection of technology blogs or all the official SharePoint blogs, for example.
 
There are several free utilities for performing RSS aggregation in SharePoint - inlcuding those that come out of the box with 2007 - but none of them work the way that I needed them to (in fact, I couldn't get the included web parts to work at all in WSS).  So I put together a basic RSS Aggregation web part that fits the bill. 
 
The functionality is really quite simple - supply the web part with a semi-colon delimited list of feed URL's, set a few parameters (like number of listings per feed, total number of listings, alternate stylesheet, etc.) and drop it onto a page.  The web part will display a list of links from each feed source sorted by publish date in descending order.  The formatting is controlled by a set of base and alternate styles that can be included in custom stylesheet or integrated with your base site definition styles.
 
You can download the RssAggregator web part here: http://www.binarywave.com/products/downloads/Free Utilities/BinaryWave.RssAggregator.zip.  The zip file contains the Visual Studio 2005 solution with full source code (written in C#) and a readme file with setup and configuration instructions.  Post any issues or questions as comments to this entry. 
 
Note: I discovered while putting this together that there are quite a few differing feed formats depending on which source you are trying to access.  Most RSS 2.0 and ATOM feeds should work but you may need to tweak the XML parsing methods in the source code if you are referencing a feed that uses non-standard or custom formatting in the source XML.  If you do make modifications, please post them here so everyone can benefit from your changes.

Comments

thanks

I've been looking for something like this for a while.

(Oh, and you do know the comments box obscures the blog text in FireFox?)
System Account on 5/15/2007 9:40 PM

I'm not seeing it in the Site Settings | Web Parts | New

I don't see the listing in the new page.
The listing is in the web.config and i've done an IIS reset.
The DLL is in the correct bin directory.

What else could I be missing?
Thanks
Ron
System Account on 5/16/2007 8:37 AM

I'm not seeing it in the Site Settings | Web Parts | New

I don't see the listing in the new page.
The listing is in the web.config and i've done an IIS reset.
The DLL is in the correct bin directory.

What else could I be missing?
Thanks
Ron
System Account on 5/16/2007 8:42 AM

Error when adding RssAggregator to the Page

I can add it to the page and set the parameters, but when I end editing of the page, it throws an error and I have to use webpart maintenance to delete it. Has anyone else seen this happen or have any ideas about the cause?

Joel
System Account on 6/12/2007 9:43 AM

Edit or Specify an XSLT

I notice that you're doing all the formatting in the code. I wonder if you might provide an update that allows you to modify the XSL that is used to present the feed.

(BTW the error mentioned in my previous post corrected itself on its own.)
System Account on 6/13/2007 4:57 PM

Re: Edit or Specify and XSLT

I'm not much of an XSL person and I was in a hurry so I did it old school.  If anyone has XSL to format the RSS XML I'd be happy to include that code in the output and add an XSL parameter to the web part settings.   Anyone???
System Account on 6/13/2007 5:14 PM

Some XSLT

Siegfried Weber wrote some XSLT for the XML web part in 2004 that works pretty well. His site seems to have disappeared off the web.

I don't know what I can fit in this comment box, but here is one of them:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:rss="http://purl.org/rss/1.0/"
   xmlns:rdf09="http://my.netscape.com/rdf/simple/0.9/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/">

<xsl:output method="html" indent="yes"/>

<xsl:template name="includeScript">
<style type="text/css">
<![CDATA[
.Header
{
background-color: #f1f1f1;
}
.Header a, .Header a:active, .Header a:visited, .Header a:hover
{
color: black;
text-decoration: none;
}
.HeaderCollapse
{
background-color: #f1f1f1;
font-weight: bold;
padding-left: 0.2em;
width: 17px;
}
.HeaderCollapse a, .HeaderCollapse a:visited, .HeaderCollapse a:active, .HeaderCollapse a:hover
{
background-color: white;
border: 1px #707070 solid;
color: black;
display: block;
font-family: Tahoma, Verdana, Sans-Serif;
font-size: 8px;
height: 10px;
text-decoration: none;
width: 10px;
}
.Content
{
margin-top: -16px;
}
]]>
</style>

<script language="JavaScript" type="text/javascript">
<![CDATA[
function ExpGroup(szID, oElement)
{
var oID = document.getElementById(szID);
if (oElement.innerHTML == "-")
{
oElement.innerHTML = "+";
oElement.title= "Expand";
oID.style.display = "none";
}
else
{
oElement.innerHTML = "-";
oElement.title= "Collapse";
oID.style.display = "block";
}
try
{
window.event.returnValue = false;
window.event.cancelBubble = true;
}
catch (e) { }
}
]]>
</script>
</xsl:template>

<xsl:template match="rdf:RDF">
<xsl:variable name="IsEmptyRSS" select="not (rss:channel/rss:title)"/>
<xsl:variable name="IsEmptyRDF" select="not (rdf09:channel/rdf09:title)"/>
<xsl:choose>
<xsl:when test="not ($IsEmptyRDF)">
<xsl:call-template name="rdf_09" />
</xsl:when>
<xsl:when test="not ($IsEmptyRSS)">
<xsl:call-template name="rss_1" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="rss_1" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="rss">
<xsl:choose>
<xsl:when test="@version = '2.0'">
<xsl:call-template name="rss_2" />
</xsl:when>
<xsl:when test="@version = '0.91'">
<xsl:call-template name="rss_091" />
</xsl:when>
<xsl:when test="@version = '0.92'">
<xsl:call-template name="rss_092" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="rss" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="rss">
<xsl:call-template name="includeScript" />

<div align="center"><h3><a target="_blank"><xsl:attribute name="title"><xsl:value-of select="channel/description" /></xsl:attribute><xsl:attribute name="href"><xsl:value-of select="channel/link" /></xsl:attribute><xsl:value-of select="channel/title" /></a></h3></div>
<div style="padding-left: 5px; padding-right: 5px; padding-bottom: 5px;">
<table class="Content" cellspacing="0" cellpadding="1">
<xsl:for-each select="channel/item">
<xsl:variable name="TopicID" select="generate-id(link)" />
<tr>
<td class="HeaderCollapse" align="center">
<a style="cursor: pointer; cursor: hand;" title="Expand"><xsl:attribute name="onclick">javascript:ExpGroup('<xsl:value-of select="$TopicID"/>', this)</xsl:attribute>+</a>
</td>
<td class="Header" style="width: 100%">
<a target="_blank"><xsl:attribute name="href"><xsl:value-of select="link" /></xsl:attribute>
<xsl:choose>
<xsl:when test="title != ''">
<xsl:value-of select="title" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="link" />
</xsl:otherwise>
</xsl:choose>
</a>
</td>
</tr>
<tr>
<td colspan="2">
<div style="display: none; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 10px; padding-right: 10px;"><xsl:attribute name="id"><xsl:value-of select="$TopicID"/></xsl:attribute>
<xsl:variable name="IsEmpty" select="not (description)"/>
<xsl:choose>
<xsl:when test="description = ''">
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:when>
<xsl:when test="not ($IsEmpty)">
<xsl:value-of disable-output-escaping="yes" select="description" />
</xsl:when>
<xsl:otherwise>
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:otherwise>
</xsl:choose>
</div>
</td>
</tr>
</xsl:for-each>
</table>
</div>
</xsl:template>

<xsl:template name="rss_091">
<xsl:call-template name="includeScript" />

<div align="center"><h3><a target="_blank"><xsl:attribute name="title"><xsl:value-of select="channel/description" /></xsl:attribute><xsl:attribute name="href"><xsl:value-of select="channel/link" /></xsl:attribute><xsl:value-of select="channel/title" /></a></h3></div>
<div style="padding-left: 5px; padding-right: 5px; padding-bottom: 5px;">
<table class="Content" cellspacing="0" cellpadding="1">
<xsl:for-each select="channel/item">
<xsl:variable name="TopicID" select="generate-id(link)" />
<tr>
<td class="HeaderCollapse" align="center">
<a style="cursor: pointer; cursor: hand;" title="Expand"><xsl:attribute name="onclick">javascript:ExpGroup('<xsl:value-of select="$TopicID"/>', this)</xsl:attribute>+</a>
</td>
<td class="Header" style="width: 100%">
<a target="_blank"><xsl:attribute name="href"><xsl:value-of select="link" /></xsl:attribute>
<xsl:choose>
<xsl:when test="title != ''">
<xsl:value-of select="title" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="link" />
</xsl:otherwise>
</xsl:choose>
</a>
</td>
</tr>
<tr>
<td colspan="2">
<div style="display: none; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 10px; padding-right: 10px;"><xsl:attribute name="id"><xsl:value-of select="$TopicID"/></xsl:attribute>
<xsl:variable name="IsEmpty" select="not (description)"/>
<xsl:choose>
<xsl:when test="description = ''">
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:when>
<xsl:when test="not ($IsEmpty)">
<xsl:value-of disable-output-escaping="yes" select="description" />
</xsl:when>
<xsl:otherwise>
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:otherwise>
</xsl:choose>
</div>
</td>
</tr>
</xsl:for-each>
</table>
</div>
</xsl:template>

<xsl:template name="rss_092">
<xsl:call-template name="includeScript" />

<div align="center"><h3><a target="_blank"><xsl:attribute name="title"><xsl:value-of select="channel/description" /></xsl:attribute><xsl:attribute name="href"><xsl:value-of select="channel/link" /></xsl:attribute><xsl:value-of select="channel/title" /></a></h3></div>
<div style="padding-left: 5px; padding-right: 5px; padding-bottom: 5px;">
<table class="Content" cellspacing="0" cellpadding="1">
<xsl:for-each select="channel/item">
<xsl:variable name="TopicID" select="generate-id(description)" />
<tr>
<td class="HeaderCollapse" align="center">
<a style="cursor: pointer; cursor: hand;" title="Expand"><xsl:attribute name="onclick">javascript:ExpGroup('<xsl:value-of select="$TopicID"/>', this)</xsl:attribute>+</a>
</td>
<td class="Header" style="width: 100%">
<a target="_blank">
<xsl:choose>
<xsl:when test="source/@url != ''">
<xsl:attribute name="href"><xsl:value-of select="source/@url" /></xsl:attribute>
</xsl:when>
<xsl:when test="enclosure/@url != ''">
<xsl:attribute name="href"><xsl:value-of select="enclosure/@url" /></xsl:attribute>
</xsl:when>
<xsl:when test="link != ''">
<xsl:attribute name="href"><xsl:value-of select="link" /></xsl:attribute>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="title != ''">
<xsl:value-of select="title" />
</xsl:when>
<xsl:when test="enclosure/@url != ''">
<xsl:value-of select="enclosure/@url" />
</xsl:when>
<xsl:when test="source/@url != ''">
<xsl:value-of select="source/@url" />
</xsl:when>
<xsl:otherwise>
<xsl:text disable-output-escaping="yes">(No Title)</xsl:text>
</xsl:otherwise>
</xsl:choose>
</a>
</td>
</tr>
<tr>
<td colspan="2">
<div style="display: none; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 10px; padding-right: 10px;"><xsl:attribute name="id"><xsl:value-of select="$TopicID"/></xsl:attribute>
<xsl:variable name="IsEmpty" select="not (description)"/>
<xsl:choose>
<xsl:when test="description = ''">
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:when>
<xsl:when test="not ($IsEmpty)">
<xsl:value-of disable-output-escaping="yes" select="description" />
</xsl:when>
<xsl:otherwise>
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:otherwise>
</xsl:choose>
</div>
</td>
</tr>
</xsl:for-each>
</table>
</div>
</xsl:template>

<xsl:template name="rss_1">
<xsl:call-template name="includeScript" />

<div align="center"><h3><a target="_blank"><xsl:attribute name="title"><xsl:value-of select="rss:channel/rss:title" /></xsl:attribute><xsl:attribute name="href"><xsl:value-of select="rss:channel/rss:link" /></xsl:attribute><xsl:value-of select="rss:channel/rss:title" /></a></h3></div>
<div style="padding-left: 5px; padding-right: 5px; padding-bottom: 5px;">
<table class="Content" cellspacing="0" cellpadding="1">
<xsl:for-each select="rss:item">
<xsl:variable name="TopicID" select="generate-id(rss:link)" />
<tr>
<td class="HeaderCollapse" align="center">
<a style="cursor: pointer; cursor: hand;" title="Expand"><xsl:attribute name="onclick">javascript:ExpGroup('<xsl:value-of select="$TopicID"/>', this)</xsl:attribute>+</a>
</td>
<td class="Header" style="width: 100%">
<a target="_blank"><xsl:attribute name="href"><xsl:value-of select="rss:link" /></xsl:attribute>
<xsl:choose>
<xsl:when test="rss:title != ''">
<xsl:value-of select="rss:title" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="rss:link" />
</xsl:otherwise>
</xsl:choose>
</a>
</td>
</tr>
<tr>
<td colspan="2">
<div style="display: none; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 10px; padding-right: 10px;"><xsl:attribute name="id"><xsl:value-of select="$TopicID"/></xsl:attribute>
<xsl:variable name="IsEmpty" select="not (rss:description)"/>
<xsl:choose>
<xsl:when test="description = ''">
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:when>
<xsl:when test="not ($IsEmpty)">
<xsl:value-of disable-output-escaping="yes" select="rss:description" />
</xsl:when>
<xsl:otherwise>
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:otherwise>
</xsl:choose>
</div>
</td>
</tr>
</xsl:for-each>
</table>
</div>
</xsl:template>

<xsl:template name="rdf_09">
<xsl:call-template name="includeScript" />

<div align="center"><h3><a target="_blank"><xsl:attribute name="title"><xsl:value-of select="rdf09:channel/rdf09:title" /></xsl:attribute><xsl:attribute name="href"><xsl:value-of select="rdf09:channel/rdf09:link" /></xsl:attribute><xsl:value-of select="rdf09:channel/rdf09:title" /></a></h3></div>
<div style="padding-left: 5px; padding-right: 5px; padding-bottom: 5px;">
<table class="Content" cellspacing="0" cellpadding="1">
<xsl:for-each select="rdf09:item">
<xsl:variable name="TopicID" select="generate-id(rdf09:link)" />
<tr>
<td class="HeaderCollapse" align="center">
<a style="cursor: pointer; cursor: hand;" title="Expand"><xsl:attribute name="onclick">javascript:ExpGroup('<xsl:value-of select="$TopicID"/>', this)</xsl:attribute>+</a>
</td>
<td class="Header" style="width: 100%">
<a target="_blank"><xsl:attribute name="href"><xsl:value-of select="rdf09:link" /></xsl:attribute>
<xsl:choose>
<xsl:when test="rdf09:title != ''">
<xsl:value-of select="rdf09:title" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="rdf09:link" />
</xsl:otherwise>
</xsl:choose>
</a>
</td>
</tr>
<tr>
<td colspan="2">
<div style="display: none; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 10px; padding-right: 10px;"><xsl:attribute name="id"><xsl:value-of select="$TopicID"/></xsl:attribute>
<xsl:variable name="IsEmpty" select="not (rdf09:description)"/>
<xsl:choose>
<xsl:when test="description = ''">
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:when>
<xsl:when test="not ($IsEmpty)">
<xsl:value-of disable-output-escaping="yes" select="rdf09:description" />
</xsl:when>
<xsl:otherwise>
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:otherwise>
</xsl:choose>
</div>
</td>
</tr>
</xsl:for-each>
</table>
</div>
</xsl:template>

<xsl:template name="rss_2">
<xsl:call-template name="includeScript" />

<div align="center"><h3><a target="_blank"><xsl:attribute name="title"><xsl:value-of select="channel/description" /></xsl:attribute><xsl:attribute name="href"><xsl:value-of select="channel/link" /></xsl:attribute><xsl:value-of select="channel/title" /></a></h3></div>
<div style="padding-left: 5px; padding-right: 5px; padding-bottom: 5px;">
<table class="Content" cellspacing="0" cellpadding="1">
<xsl:for-each select="channel/item">
<xsl:variable name="TopicID" select="generate-id(link)" />
<tr>
<td class="HeaderCollapse" align="center">
<a style="cursor: pointer; cursor: hand;" title="Expand"><xsl:attribute name="onclick">javascript:ExpGroup('<xsl:value-of select="$TopicID"/>', this)</xsl:attribute>+</a>
</td>
<td class="Header" style="width: 100%">
<a target="_blank">
<xsl:choose>
<xsl:when test="guid != ''">
<xsl:attribute name="href"><xsl:value-of select="guid" /></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="href"><xsl:value-of select="link" /></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="title != ''">
<xsl:value-of select="title" />
</xsl:when>
<xsl:when test="guid != ''">
<xsl:value-of select="guid" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="link" />
</xsl:otherwise>
</xsl:choose>
</a>
</td>
</tr>
<tr>
<td colspan="2">
<div style="display: none; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 10px; padding-right: 10px;"><xsl:attribute name="id"><xsl:value-of select="$TopicID"/></xsl:attribute>
<xsl:variable name="IsEmpty" select="not (description)"/>
<xsl:choose>
<xsl:when test="description = ''">
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:when>
<xsl:when test="not ($IsEmpty)">
<xsl:value-of disable-output-escaping="yes" select="description" />
</xsl:when>
<xsl:otherwise>
<xsl:text disable-output-escaping="yes">No description available</xsl:text>
</xsl:otherwise>
</xsl:choose>
</div>
</td>
</tr>
</xsl:for-each>
</table>
</div>
</xsl:template>

</xsl:stylesheet>
System Account on 6/14/2007 4:03 AM

Any progress adding ability to Edit the XSL

I've tried to implement this XSL directly into the 'Alternate Stylesheet' field in the properties of the Feedlistings web part. I've also tried to separate the feeds by enter a multiple headers into the Feed Headers property. No luck.

Do you expect to work on the Feedlistings web part any more to add some additional ability to control the appearance of the feeds? It would be very helpful.

Thanks!
System Account on 8/27/2007 4:16 PM

Authenticating an RSS Feed

I have a requirement to authenticate RSS feeds. Does BinaryWave have this capability?
System Account on 9/4/2007 1:37 PM

Great webpart

Is there a way to display a portion of the text of the feed? Also, and this is the most important, is there a way to make all the links open in a new window? I hate having people leave my site just to view a piece of news.
System Account on 9/26/2007 1:23 PM
1 - 10Next

Add Comment

Items on this list require content approval. Your submission will not appear in public views until approved by someone with proper rights. More information on content approval.

Title


Body *


Comment Date *

Select a date from the calendar.
Enter the current date to prevent automated spambot comments.

Spam Prevention *


How many letters, not including spaces, does it take to spell "SharePoint Cowboy"?

Attachments

 

 




Copyright © 2013 BinaryWave, Inc. All rights reserved.