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.

rss-cine.jpg

Comments (3)

  1. Duncanma says:

    Is there a way to use the managed web browser to set the security zone so that any script that sneaks it way into an RSS entry wouldn’t be executed in your basic feed reader?

  2. WinFormsUE says:

    From what I can tell, you’d have to use WebBrowserSiteBase so that you could monkey around with IDocHostUIHandler:

    http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/hosting/wbcustomization.asp

    I was in the early spec reviews for this meeting (I used to be PM for this control and Managed HTML DOM). I believe we had talked about exposing a way to do this, but for some reason decided not to.

    I’ll look into this tomorrow, and report back on any success or failure.

  3. So I’m trying to wrap up this white paper I’m writing on consuming RSS in Windows Forms. I wrote a whole…