An
RSS feed is merely an XML file generated at regular intervals, consumed
by an application that knows what to do with it. Therefore, it’s really
just putting together pieces you already know: web download and XML
parsing.
The
accompanying source code for this article contains two projects: RssLib
and RssReader. The following sample is from RssLib and contains some
simple feed parsing code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Net;
using System.Globalization;
namespace RssLib
{
public class Channel
{
public string Title { get; set; }
public string Link { get; set; }
public string Description { get; set; }
public CultureInfo Culture { get; set; }
public List<Item> Items { get; set; }
}
public class Item
{
public string Title { get; set; }
public string Link { get; set; }
public string Comments { get; set; }
public string PubDate { get; set; }
public string Description { get; set; }
}
public class Feed
{
public Channel Read(string url)
{
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
XmlDocument doc = new XmlDocument();
try
{
doc.Load(response.GetResponseStream());
Channel channel = new Channel();
XmlElement rssElem = doc["rss"];
if (rssElem == null) return null;
XmlElement chanElem = rssElem["channel"];
if (chanElem != null)
{
//only read a few of the many possible fields
channel.Title = chanElem["title"].InnerText;
channel.Link = chanElem["link"].InnerText;
channel.Description =
chanElem["description"].InnerText;
channel.Culture = CultureInfo.CreateSpecificCulture(chanElem["language"].InnerText);
channel.Items = new List<Item>();
XmlNodeList itemElems =
chanElem.GetElementsByTagName("item");
foreach (XmlElement itemElem in itemElems)
{
Item item = new Item();
item.Title = itemElem["title"].InnerText;
item.Link = itemElem["link"].InnerText;
item.Description =
itemElem["description"].InnerText;
item.PubDate = itemElem["pubDate"].InnerText;
item.Comments = itemElem["comments"].InnerText;
channel.Items.Add(item);
}
}
return channel;
}
catch (XmlException)
{
return null;
}
}
public void Write(Stream stream, Channel channel)
{
XmlWriter writer = XmlTextWriter.Create(stream);
writer.WriteStartElement("rss");
writer.WriteAttributeString("version", "2.0");
writer.WriteStartElement("channel");
writer.WriteElementString("title", channel.Title);
writer.WriteElementString("link", channel.Link);
writer.WriteElementString("description",
channel.Description);
writer.WriteElementString("language",
channel.Culture.ToString());
foreach (Item item in channel.Items)
{
writer.WriteStartElement("item");
writer.WriteElementString("title", item.Title);
writer.WriteElementString("link", item.Link);
writer.WriteElementString("description",
item.Description);
writer.WriteElementString("pubDate", item.PubDate);
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndElement();
writer.Flush();
}
}
}
Here’s a short sample of how this library is used:
private void buttonLoad_Click(object sender, EventArgs e)
{
LoadFeed(textBoxFeed.Text);
}
private void LoadFeed(string url)
{
listViewEntries.Items.Clear();
RssLib.Channel channel = _feed.Read(url);
this.Text = "RSS Reader - " + channel.Title;
foreach (RssLib.Item item in channel.Items)
{
ListViewItem listViewItem = new
ListViewItem(item.PubDate.ToString());
listViewItem.SubItems.Add(item.Title);
listViewItem.SubItems.Add(item.Link);
listViewItem.Tag = item;
listViewEntries.Items.Add(listViewItem);
}
}
In a complete implementation, RSS can have many more fields than are presented here. See http://www.rssboard.org/rss-specification for the full specification of required and optional elements.