RSS - C#/VB.NET implementations

June 23, 2008 by C#   Visual Basic  

There is a number of ways to read a RSS feed in .net, I am going to look at four different solutions to do this.

The following code is by no means a mature solution (it assumes a lot of things), and should soley be used as a starting point - ensure that you've got sufficient exception handling.

Looking at the namespaces, we'll be using a generic list (System.Collections.Generic) for our items, which we can easily bind to a datasource.

We're going to have a look at using Linq (System.Linq & System.Xml.Linq), and have a look at Microsofts' WCF syndication (System.ServiceModel.Syndication - which you can find in the System.ServiceModel.Web component in .net 3.5)

using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Xml;
using System.Xml.Linq;
Imports System.Collections.Generic
Imports System.Linq
imports System.ServiceModel.Syndication
imports System.Xml
imports System.Xml.Linq

a simple struct/structure, which will contain the rss items

public struct RSSItem
{
    private string _title;
    public string title
    {
        get
        {
            return _title;
        }
        set
        {
            _title = value;
        }
    }

    private string _link;
    public string link
    {
        get
        {
            return _link;
        }
        set
        {
            _link = value;
        }
    }

    private string _description;
    public string description
    {
        get
        {
            return _description;
        }
        set
        {
            _description = value;
        }
    }
}
Public Structure RSSItem
    Private _title As String
    Public Property title() As String
        Get
            Return _title
        End Get
        Set(ByVal value As String)
            _title = value
        End Set
    End Property

    Private _link As String
    Public Property link() As String
        Get
            Return _link
        End Get
        Set(ByVal value As String)
            _link = value
        End Set
    End Property

    Private _description As String
    Public Property description() As String
        Get
            Return _description
        End Get
        Set(ByVal value As String)
            _description = value
        End Set
    End Property
End Structure

Using the XmlDocument class

public class RSSReader
{
    public string title;
    public string link;
    public string description;
    public List<RSSItem> items = new List<RSSItem>();

    public RSSReader(string url)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(url);

        XmlElement channel = doc["rss"]["channel"];
        XmlNodeList items = channel.GetElementsByTagName("item");
        this.title = channel["title"].InnerText;
        this.link = channel["link"].InnerText;
        this.description = channel["description"].InnerText;

        foreach (XmlNode item in items)
        {
            RSSItem rssItem = new RSSItem();
            rssItem.title = item["title"].InnerText;
            rssItem.description = item["description"].InnerText;
            rssItem.link = item["link"].InnerText;
            this.items.Add(rssItem);
        }
    }
}
Public Class RSSReader

    Public title As String
    Public link As String
    Public description As String
    Public items As List(Of RSSItem) = New List(Of RSSItem)()

    Public Sub New(ByVal url As String)

        Dim doc As New XmlDocument()
        doc.Load(url)

        Dim channel As XmlElement = doc("rss")("channel")
        Dim items As XmlNodeList = channel.GetElementsByTagName("item")
        Me.title = channel("title").InnerText
        Me.link = channel("link").InnerText
        Me.description = channel("description").InnerText

        For Each item As XmlNode In items
            Dim rss As New RSSItem()
            rss.title = item("title").InnerText
            rss.description = item("description").InnerText
            rss.link = item("link").InnerText
            Me.items.Add(rss)
        Next

    End Sub
End Class

Reading RSS feed using linq

public class RSSReader
{
    public string title;
    public string link;
    public string description;
    public List items;

    public RSSReader(string url)
    {
        XElement rssFeed = XElement.Load(url).Element("channel");
        this.title = rssFeed.Element("title").Value;
        this.link = rssFeed.Element("link").Value;
        this.description = rssFeed.Element("description").Value;
        items = (from Item in rssFeed.Elements("item")
                 select new RSSItem()
                 {
                     title = Item.Element("title").Value,
                     description = Item.Element("description").Value,
                     link = Item.Element("link").Value
                 }).ToList();
    }
}
Public Class RSSReader

    Public title As String
    Public link As String
    Public description As String
    Public items As List(Of RSSItem)

    Public Sub New(ByVal url As String)

        Dim rssFeed As XElement = XElement.Load(url).Element("channel")
        Me.title = rssFeed.Element("title").Value
        Me.link = rssFeed.Element("link").Value
        Me.description = rssFeed.Element("description").Value

        items = (From Item In rssFeed.Elements("item") _
                 Select New RSSItem With { _
                    .title = Item.Element("title").Value, _
                    .description = Item.Element("description").Value, _
                    .link = Item.Element("link").Value}).ToList()

    End Sub

End Class

Using the XmlTextReader class envolves a bit more work, but this is the route you can go if you're thinking about .net 1.1 support (obviously stripping generics from this solution, since generics only appeared in .net in version 2.0)

public class RSSReader
{
    public string title;
    public string link;
    public string description;
    public List<RSSItem> items = new List<RSSItem>();

    public RSSReader(string url)
    {
        XmlTextReader reader = new XmlTextReader(url);

        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.Name)
                {
                    case "title":
                        this.title = reader.ReadString();
                        break;
                    case "link":
                        this.link = reader.ReadString();
                        break;
                    case "description":
                        this.description = reader.ReadString();
                        break;
                    case "image":
                        while (!((reader.Name == "image") &&
                                    (reader.NodeType == XmlNodeType.EndElement)) &&
                                            reader.Read()) 
                        break;
                }
            }

            if (reader.Name == "item")
            {
                RSSItem item = new RSSItem();
                while (!((reader.Name == "item") &&
                            (reader.NodeType == XmlNodeType.EndElement)) &&
                                reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        switch (reader.Name.ToLower())
                        {
                            case "title":
                                item.title = reader.ReadString();
                                break;
                            case "description":
                                item.description = reader.ReadString();
                                break;
                            case "link":
                                item.link = reader.ReadString();
                                break;
                        }
                    }
                }
                items.Add(item);
            }
        }
    }
}
Public Class RSSReader

    Public title As String
    Public link As String
    Public description As String
    Public items As List(Of RSSItem) = New List(Of RSSItem)()

    Public Sub New(ByVal url As String)

        Dim reader As New XmlTextReader(url)

        While reader.Read()
            If reader.NodeType = XmlNodeType.Element Then
                Select Case (reader.Name)
                    Case "title"
                        Me.title = reader.ReadString()
                    Case "link"
                        Me.link = reader.ReadString()
                    Case "description"
                        Me.description = reader.ReadString()
                    Case "image"
                        While (Not ((reader.Name = "image") And _
                                    (reader.NodeType = XmlNodeType.EndElement)) And _
                                            reader.Read())
                        End While
                End Select
            End If

            If reader.Name = "item" Then

                Dim item As New RSSItem()
                While (Not ((reader.Name = "item") And _
                            (reader.NodeType = XmlNodeType.EndElement)) And _
                                reader.Read())
                    If (reader.NodeType = XmlNodeType.Element) Then

                        Select Case (reader.Name.ToLower())
                            Case "title"
                                item.title = reader.ReadString()
                            Case "description"
                                item.description = reader.ReadString()
                            Case "link"
                                item.link = reader.ReadString()
                        End Select
                    End If
                End While
                items.Add(item)
            End If
        End While
    End Sub

.net 3.5 "shipped", with WCF(Windows Communication Foundation), which contains classes for generating rss 2.0 feeds and formatting them - the only con is, theses classes dont support previous rss specifications (some which are widely still in use)

XmlReader RSSReader = XmlReader.Create(@"http://rss.cnn.com/rss/cnn_space.rss");
Rss20FeedFormatter formatter = new Rss20FeedFormatter();
formatter.ReadFrom(RSSReader);
Dim RSSReader As XmlReader = XmlReader.Create("http://rss.cnn.com/rss/cnn_space.rss")
Dim formatter As Rss20FeedFormatter = New Rss20FeedFormatter()
formatter.ReadFrom(RSSReader)

Other solutions

There are many other ways to parse RSS feeds in .net, generated xsd classes (serialize/deserializing rss feeds to it using xmlserializer), using a dataset (although you might run into some schema issues), using it as a xmldatasource, using xsl(in a server side manner, client side if you dont mind cross browser compatibility) and many others.


Leave a Comment



Related Posts

RSS - PHP (4, 5) implementations

June 23, 2008

RSS - JavaScript implementations

June 23, 2008


Related Downloads

How to create a RSS Reader