Multiple Feeds Parser

There are multiple ways of parsing an RSS or Atom feed in .NET like XmlDocument and XDocument classes. If you´re running .NET Framework 3.5 and above it´s also possible to use the SyndicationFeed class and it is as simple as this:

using (var reader = XmlReader.Create(url))
{
    var feed = SyndicationFeed.Load(reader);
}

Here follows a snippet to parse multiple feeds into one using the SyndicationFeed class and some LINQ (I love LINQ :-)).

var urls = new string[] { "url-to-feed", "url-to-feed", "url-to-feed" };
var multiFeed = new SyndicationFeed();

multiFeed.Items = (from url in urls
                   from xr in XmlReader.Create(url).Use()
                   let feed = SyndicationFeed.Load(xr)
                   from i in feed.Items
                   select i)
                   .OrderByDescending(x => x.PublishDate);

But there´s one issue using the XmlReader inside a LINQ expression; the reader needs to be disposed to free up resources. One way would be using a method – named or anonymous – called from the query. But searching around led me to a neat solution using an extension method that turns an IDisposable object into a single-element sequence. The C# compiler will build an iterator that properly handles the finally clause, ensuring the object will be disposed.

public static IEnumerable<T> Use<T>(this T obj)
    where T : IDisposable
{
    try
    {
        yield return obj;
    }
    finally
    {
        if (obj != null)
        {
            obj.Dispose();
        }
    }
}

Heads-Up

If for example parsing a feed from feedburner, you´ll probably get an error when parsing DateTime value in the XML. The Atom feed they provide is not valid and the W3C validator says: pubDate must be an RFC-822.

Conclusion: If parsing feeds via SyndicationFeed it would be a great idea having a backup method, in case the SyndicationFeed instance fails to parse the feed correctly.