Using WebBrowser in Windows Forms to View Blog Content Syndicated Through RSS
With the managed WebBrowser control in Windows Forms 2.0, it's a snap to take an RSS feed and display it as formatted HTML text in the browser. Using transformed RSS in lieu of the original site has several benefits: the transformed RSS is usually faster to load; you can manipulate it programmatically with ease to create a standard feel for all syndicated content; and you can easily switch from one blog site to another - perfect if you're building some type of branded RSS reader.
The first thing you need is a way to turn RSS into HTML. I chose to create an XSLT (XSL Transform) document to do the job:
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:content="http://purl.org/rss/1.0/modules/content/">
<xsl:template match="/rss/channel">
<HTML>
<HEAD>
<TITLE>
<xsl:value-of select="title"/>
</TITLE>
<STYLE>
.PostTitle {
font-size:16px;
font-weight:bold;
}
</STYLE>
</HEAD>
<BODY>
<DIV class="RssHeader">
<xsl:for-each select="image">
<xsl:element name="IMG">
<xsl:attribute name="src">
<xsl:value-of select="url"/>
</xsl:attribute>
<xsl:attribute name="style">
float:left;
</xsl:attribute>
</xsl:element>
</xsl:for-each>
<h2>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="link" />
</xsl:attribute>
<xsl:value-of select="title"/>
</xsl:element>
</h2>
<span class="Errata">
<strong>Description</strong>:
<xsl:value-of select="description"/>
</span>
<br/>
<span class="Errata">
<strong>Generated By</strong>:
<xsl:value-of select="generator"/>
</span>
<p/>
<span class="Errata">
<xsl:value-of select="copyright"/>
</span>
</DIV>
<HR/>
<BR/>
<xsl:for-each select="item">
<DIV class="PostTitle">
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="link" />
</xsl:attribute>
<xsl:value-of select="title"/>
</xsl:element>
</DIV>
<DIV class="PostAuthor">
Author: <xsl:value-of select="dc:creator"/>
</DIV>
<DIV class="PostDate">
Published on <xsl:value-of select="dc:date"/>
</DIV>
<DIV class="PostContent">
<xsl:value-of select="description" disable-output-escaping="yes"/>
</DIV>
<BR/>
<HR/>
<BR/>
</xsl:for-each>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
Now, however, we need a way to execute the transform in code. Not a problem: Just use the XslCompiledTransform class defined in System.Xml.Xsl to pull this off. (NOTE: I do all exception handling in the caller of this method.)
private StringBuilder TransformFeed(Uri feedUri, string xsltPath)
{
StringBuilder writtenHtmlString = new StringBuilder();
XmlWriter writtenHtml = null;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(feedUri.ToString());
writtenHtml = XmlWriter.Create(writtenHtmlString);
// Perform a transform.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xsltPath);
xslt.Transform(xmlDoc, writtenHtml);
writtenHtml.Close();
return (writtenHtmlString);
}
Assign this HTML to the DocumentText property of the WebBrowser control on your form, and you're golden. Add a TreeView to your app to maintain a list of categorized blog feed, throw in a persistence mechanism for the user's list of blogs to watch (say, perhaps, Application Settings?), and you have yourself a basic RSS feed reader in Windows Forms.