Friday, May 23, 2008

Slapdash - Putting feeds on your page the easy way

I wanted to read RSS into a DataSet but found that when loading the XML from, for example, a community server feed I would often get a 'column already exists'. This was because the feed used namespaces which causes elements to be declared like this: <slash:comment>

There are two solutions to this. First, write an XSLT to parse out the stuff I don't want. Second, run over the raw XML myself and filter it. I wanted to go with the second, because writing XSLT for every customised RSS, ATOM, etc feed that my front end developers might want to use didn't appeal - I just wanted to be able to load the RSS into a DataSet. However, then I found some code which seemed to work:

The one problem I had was that the code did not seem to know when an element like <enclosure/> did not have a closing tag following it. I have fixed this code and present it below. I have used it to load the header information and each item entry in the RSS feed into a couple of repeaters, for quick databinding, so that I can provide a simple data layout for my front end designer to work with. He can then style this anyway he likes and I can even wrap the items table in a DataView to sort and filter it by any combination of fields in the feed. Of course, because this uses a DataSet, I could even merge other feeds into it.

Many thanks to, er, admin(?), for writing the original - you really have helped me a lot!...

    protected void Page_Load(object sender, EventArgs e)
DataSet set = new DataSet();
XmlTextReader xmlRdr = new XmlTextReader("");
XmlDocument doc = new XmlDocument();

set = GetRSSDataSet("");

headerRepeater.DataSource = set.Tables[1];
itemsRepeater.DataSource = set.Tables[2];


public DataSet GetRSSDataSet(string m_strAdress)
DataSet m_ds = new DataSet();

System.Xml.XmlTextReader oXml = new System.Xml.XmlTextReader(m_strAdress);
oXml.WhitespaceHandling = System.Xml.WhitespaceHandling.None;
System.Text.StringBuilder oBuilder = new StringBuilder();

bool fContinue = oXml.Read();
while (fContinue)
string sName = oXml.Name.Replace(":", "_");
bool isClosed = oXml.IsEmptyElement;
if (oXml.NodeType == System.Xml.XmlNodeType.Element)
//Add the element...
oBuilder.Append("&lt;" + sName);
if (oXml.HasAttributes)
while (oXml.MoveToNextAttribute())
sName = oXml.Name.Replace(":", "_");
oBuilder.AppendFormat(" " + sName + "=\"" + oXml.Value + "\"");
if (isClosed)
else if (oXml.NodeType == System.Xml.XmlNodeType.Text)
else if (oXml.NodeType == System.Xml.XmlNodeType.EndElement)
oBuilder.Append("&lt;/" + sName + "&gt;");

fContinue = oXml.Read();

string sXmlResult = oBuilder.ToString();

m_ds = new DataSet();
System.IO.StringReader oStringReader = new System.IO.StringReader(sXmlResult);
m_ds.ReadXml(oStringReader, System.Data.XmlReadMode.Auto);
catch (Exception ex)
m_ds = null;
if (oStringReader != null)
if (oXml != null)
return m_ds.Tables.Count == 0 ? null : m_ds;
 [EDIT: 2008-06-20] I have a .NET3.5 new and improved version of this, which allows multiple feeds and optional sorting - I'll post this later.
[EDIT: 2009-02-19] Sorry for not having posted the replacement of this code.  I will, when I find it.  A lot has happened since the original posting.  

No comments:

Post a Comment