Recently, I've been going through the standard fatherhood ritual of trying to setup of a webpage to share out photos of my kid. This naturally involves creating an RSS feed so that family can subscribe to the new image list.

I wanted to be able to write simple C# code like this to produce the feed:

    static void WriteWholeFile()
        XmlWriter xml = new XmlTextWriter(new StreamWriter("myfeed.xml"));
        RssWriter rss = new RssWriter(xml);

        rss.WriteHeader("My Mini blog", "", "My site of baby pictures", null);
            "First item",
            "Hi! Here's the <b>first</b> item",
            new System.Uri(""),
             new DateTime(1999, 12, 1));

            "Second item",
            "Here's the <b>2nd</b> item.",
            new System.Uri(""),
            new DateTime(1988, 10, 4));

Here's some trivia about some of the decisions I made here:

  • I'm no RSS/XML/Web expert, so I have no doubt there are many better implementations out there.
  • Copying one of these other writers would violate the unspoken rules of this standard fatherhood ritual. (as would using Flickr)
  • My main goal was simplicity, as illustrated by the usage snippet above.
  • It's producing valid RSS 2.0 feeds. You can validate the feeds by URL at, or by pasting in the text at And they also work in SharpReader (which is what my target audience is using).
  • DateTimeFormatInfo is a live-saver to get the the DateTime into the date format needed for an RSS feed.
  • Since RSS is just XML, I choose to build RSSWriter on an XmlWriter. This lets the caller have great flexibility about where the XML goes (a local file, a string, a node in an XML Dom)
  • The RSSWriter does not own the underlying XmlWriter, and so RSSWriter.Close() does not close the underlying streams.
  • I avoided XML Serialization (the method Dare used in RSSBandit) because I wanted a simple, forward writing, stateless, writer. This is similar to using XmlWriter over the XML Dom.

Here's the code:  [Updated: made some minor tweaks, including rename RSS-->Rss per fxcop guidelines]

using System;
using System.Xml;
using System.IO;

// Class to write out RSS
// Expected Usage:
//  rss = new RSSWriter(...);
//  rss.WriteHeader(...);
//    rss.WriteItem(..);
//    rss.WriteItem(..);
//    rss.WriteItem(..);
//  rss.Close();

// Validate feeds by URL:, or
// Code for RSS writer from  
class RssWriter
    XmlWriter m_writer;
    public RssWriter(XmlWriter tw)
        m_writer = tw;

    // Write header for RSS Feed
    // Parameters:
    // title - Pretty title of the RSS feed. Eg "My Pictures"
    // link - optional URL to link RSS feed back to a web page.
    // description - more verbose human-readable description of this feed.
    // generator - optional string for 'generator' tag.
    public void WriteHeader(string title, string link, string description, string generator)
        m_writer.WriteAttributeString("version", "2.0");
        m_writer.WriteElementString("title", title);

        if (link != null)
            m_writer.WriteElementString("link", link); // link to generated report.
        m_writer.WriteElementString("description", description);

        if (generator != null)
            m_writer.WriteElementString("generator", generator);

        m_writer.WriteElementString("lastBuildDate", ConvertDate(new DateTime()));


    // Write out an item.
    // title - title of the blog entry
    // content - main body of the blog entry
    // link - link the blog entry back to a webpage.
    // time - date for the blog entry.
    public void WriteItem(string title, string content, System.Uri link, DateTime time)
        WriteItemBody(m_writer, title, content, link, time);
        m_writer.WriteEndElement(); // item

    // Write just the body (InnerXml) of a new item
    public static void WriteItemBody(XmlWriter w, string title, string content, System.Uri link, DateTime time)
        w.WriteElementString("title", title);
        if (link != null) { w.WriteElementString("link", link.ToString()); }
        w.WriteElementString("description", content); // this will escape
        w.WriteElementString("pubDate", ConvertDate(time));

    // Close out the RSS stream.
    // this does not close the underlying XML writer.
    public void Close()
        m_writer.WriteEndElement(); // channel
        m_writer.WriteEndElement(); // rss

    // Convert a DateTime into the format needed for RSS (from RFC 822).
    // This looks like: "Wed, 04 Jan 2006 16:03:00 GMT"
    static string ConvertDate(DateTime t)

        // See this for help on format string
        DateTime t2 = t.ToUniversalTime();
        return t2.ToString(@"ddd, dd MMM yyyy HH:mm:ss G\MT");