Library code snippets

RSS Feed Helper Class

When creating the RSS feed for Developer Fusion, I decided to create a simple helper class to generate the XML for me. An example using the class follows.

using System;
using System.Xml;
/// <summary>
/// Enables the generation of an RSS feed
/// </summary>
public class RSSFeedGenerator
{
    XmlTextWriter writer;
    public RSSFeedGenerator( System.IO.Stream stream, System.Text.Encoding encoding )
    {
        writer = new XmlTextWriter(stream, encoding);
        writer.Formatting = Formatting.Indented;
    }
    public RSSFeedGenerator( System.IO.TextWriter w )
    {
        writer = new XmlTextWriter(w);
        writer.Formatting = Formatting.Indented;
    }
    /// <summary>
    /// Writes the beginning of the RSS document
    /// </summary>
    public void WriteStartDocument()
    {
        writer.WriteStartDocument();
        writer.WriteStartElement("rss");
        writer.WriteAttributeString("version","2.0");
    }
    /// <summary>
    /// Writes the end of the RSS document
    /// </summary>
    public void WriteEndDocument()
    {
        writer.WriteEndElement(); //rss
        writer.WriteEndDocument();
    }
    /// <summary>
    /// Closes this stream and the underlying stream
    /// </summary>
    public void Close()
    {
        writer.Flush();
        writer.Close();
    }
    /// <summary>
    /// Begins a new channel in the RSS document
    /// </summary>
    /// <param name="title"></param>
    /// <param name="link"></param>
    /// <param name="description"></param>
    public void WriteStartChannel(string title, string link, string description, string copyright, string webMaster)
    {
        writer.WriteStartElement("channel");
        writer.WriteElementString("title",title);
        writer.WriteElementString("link",link);
        writer.WriteElementString("description",description);
        writer.WriteElementString("language","en-gb");
        writer.WriteElementString("copyright",copyright);
        writer.WriteElementString("generator","Developer Fusion RSS Feed Generator v1.0");
        writer.WriteElementString("webMaster",webMaster);
        writer.WriteElementString("lastBuildDate",DateTime.Now.ToString("r"));
        writer.WriteElementString("ttl","20");
       
    }
    /// <summary>
    /// Writes the end of a channel in the RSS document
    /// </summary>
    public void WriteEndChannel()
    {
        writer.WriteEndElement(); //channel
    }
    /// <summary>
    /// Writes an item to a channel in the RSS document
    /// </summary>
    /// <param name="title"></param>
    /// <param name="link"></param>
    /// <param name="description"></param>
    /// <param name="author"></param>
    /// <param name="publishedDate"></param>
    /// <param name="category"></param>
    public void WriteItem(string title, string link, string description, string author, DateTime publishedDate, string subject)
    {
        writer.WriteStartElement("item");
        writer.WriteElementString("title",title);
        writer.WriteElementString("link",link);
        writer.WriteElementString("description",description);
        writer.WriteElementString("author",author);
        writer.WriteElementString("pubDate",publishedDate.ToString("r"));
        //writer.WriteElementString("category",category);
        writer.WriteElementString("subject",subject);
        writer.WriteEndElement();
    }
}

and then it was *really* simple to generate the RSS feed! :)

// set the content type
Page.Response.ContentType = "text/xml";
// create a RSS feed generator for the output
RSSFeedGenerator gen = new RSSFeedGenerator(Page.Response.Output);
gen.WriteStartDocument();
gen.WriteStartChannel("Developer Fusion RSS Feed",
    "http://www.developerfusion.com/",
    "Summary of the latest articles published on Developer Fusion",
    "Copyright © Developer Fusion Ltd, 1999-2004", "James Crowley" );
// generate the items here
gen.WriteItem("Using ADO.NET with SQL Server",
    "http://www.developerfusion.com/show/4278/",
    "An extensive examination of using ADO.NET to access SQL Server databases, from establishing connections and executing stored procedures, to connection pools, data readers and data sets.",
    "James Crowley", DateTime.Now, ".NET");
// clear up
gen.WriteEndChannel();
gen.WriteEndDocument();
gen.Close();

Comments

  1. 19 Dec 2006 at 04:20

    When I run the sample, I got this error :

     

    The XML page cannot be displayed

    Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.


    Cannot have a DOCTYPE declaration outside of a prolog. Error processing resource 'http://localhost/TestLibrary/Default.aspx...

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    ----------^

     

     

    Please anyone advise me to solve the problem, thanks in advance.

  2. 19 Aug 2004 at 08:23

    thanks for this it helped a lot!  Here's a simple pruning function which would remove past ttl items from the rss feed once its up.  NOTE: i don't correct for time zones if specified at the end of <pubDate>, though you easily could in the for loop.


    Code:

    /// <summary>
       /// Attempts to remove items past their time to live value by opening the RSS feed as an xml document and remove the elements with expired ttl
       /// </summary>
       /// <param name="XmlFileStream">a System.IO.Stream of the feed xml</param>
       /// <returns>updated document as System.IO.Stream</returns>
       public System.IO.Stream PrunePastTtl_getStream(System.IO.Stream XmlFeed)
       {
           XmlDocument        feedDoc    = new XmlDocument();
           XmlNode            docfrag;
           XmlNodeList        nodelist;
           int                prunettl;


           DateTime        TargetPruneDt;
           TimeSpan        ttlTime;


           try
           {
               feedDoc.Load(XmlFeed);


               nodelist = feedDoc.GetElementsByTagName("channel");            
               docfrag = nodelist.Item(0);


               
               string ttlstring = docfrag.InnerXml;


               int begin = ttlstring.IndexOf("<ttl>") + 5;
               int end = ttlstring.IndexOf(@"</ttl>");


               ttlstring = ttlstring.Substring(begin,(end - begin));


               
               prunettl = Convert.ToInt32(ttlstring);
               ttlTime = new TimeSpan(prunettl,0,0,0);
               
               TargetPruneDt = DateTime.Now.Subtract(ttlTime);


               // at this point should know the ttl so process <item>s
           
               for(int i=0; i< docfrag.ChildNodes.Count; i++)
               {
                   if(docfrag.ChildNodes.Item(i).Name == "item")
                   {


                       string blobOXml = docfrag.ChildNodes.Item(i).InnerXml;
                       int pubbegin = blobOXml.IndexOf("<pubDate>") + 9;
                       int pubend = blobOXml.IndexOf("</pubDate>");
                   
                       string pubdate = blobOXml.Substring(pubbegin,(pubend - pubbegin));
                   
                       if(pubdate.IndexOf("+") != -1)
                       {
                           pubdate = pubdate.Remove(pubdate.IndexOf("+"),(pubdate.Length - pubdate.IndexOf("+")));
                       }
                       else if(pubdate.IndexOf("-") != -1)
                       {
                           pubdate = pubdate.Remove(pubdate.IndexOf("-"),(pubdate.Length - pubdate.IndexOf("-")));
                       }


                       DateTime publishDate = DateTime.Parse(pubdate);


                       if(publishDate.Ticks < TargetPruneDt.Ticks)
                       {
                           docfrag.RemoveChild(docfrag.ChildNodes.Item(i));
                           i--;  // if we remove one dont want to skip one as we iterate through
                       }
                   }
               }
           
               System.IO.Stream returnval = new System.IO.MemoryStream();
               feedDoc.Save(returnval);
               returnval.Position = 0;


                       return returnval;
           }
           catch(Exception appEx)
           {
               Exception AppEx = new ApplicationException("Unable to load correctly - " + appEx.Message,appEx);
               throw AppEx;
           }


       }

  3. 17 Aug 2004 at 17:45

    Very nice wrapper

  4. 01 Jan 1999 at 00:00

    This thread is for discussions of RSS Feed Helper Class.

Leave a comment

Sign in or Join us (it's free).

James Crowley James first started this website when learning Visual Basic back in 1999 whilst studying his GCSEs. The site grew steadily over the years while being run as a hobby - to a regular monthly audience ...

Related podcasts

Events coming up

  • Mar 15

    DevWeek 2010

    London, United Kingdom

    DevWeek is Europe’s leading independent conference for software developers, database professionals and IT architects, and features expert speakers on a wide range of topics, including .NET 4.0, Silverlight 3, WCF 4, Visual Studio 2010, REST, Windows Workflow 4, Thread Synchronization, ASP.NET 4.0, SQL Server 2008 R2, LINQ, Unit Testing, CLR & C# 4.0, .NET Patterns, WPF 4, F#, Windows Azure, ADO.NET, Entity Framework, Debugging, T-SQL Tips & Tricks, and more.

Want to stay in touch with what's going on? Follow us on twitter!