Z Code

Build an RSS Generator Component

Learn how to create an RSS feed for publishing data to subscriber apps. You can use the handy RssGen sample component as a starting point for your own data feed generator.

Technology Toolbox: VB.NET, XML

You've undoubtedly tried numerous ways to distribute corporate information, including paper reports, Web reports, custom data reporting, and third-party data-analysis apps—all with varying degrees of success. The problem is that report users need to look in their mail slot, visit a Web page, or go elsewhere for your output. Instead, try Really Simple Syndication (RSS) feeds, a data-publishing technique based on the XML standard that lets you publish information both internally and externally. You create an RSS "feed" that interested parties can subscribe to using a newsreader (or aggregator) within custom apps or centralized in a module on your corporate portal.

News content generators were the first big providers of RSS feeds, and the recent surge in popularity of Weblogs (also known as blogs) has fueled interest in the RSS publishing format. Before RSS, you had to visit each of your information sources regularly to see if something had changed. You checked e-mail, visited your favorite Web sites, and looked in your mail slot for a new hardcopy report. With RSS, you point a newsreader app to all of your information sources and it collects, updates, and notifies you of what's changed and displays a summary of each with links to detailed content—all within a single interface. This is a great time-saver for your data-hungry users.

RSS originated in 1999 and reached its current version in the fall of 2002. The RSS standard is essentially frozen at version 2, but you can add custom extensions to the spec by publishing your schema through a namespace (see Additional Resources). RSS enables you to publish content easily in a standardized XML format that a reader app consumes. RSS is a content description format, so coupled with a stylesheet or other custom formatter, you can make the RSS output look any way you like on the receiving end.

The RSS feed consists of an XML file with three parts: a header, the channel definition, and a list of items (see Listing 1). The header defines the XML and RSS versions supported in your feed. The channel section is metadata describing the RSS feed itself. Items are the individual pieces of information you're actually publishing, and you can have an unlimited number of items within a channel. Many RSS elements accept HTML markup as data, so you can do things such as provide hyperlinks and embed images in your content.

This column's sample code consists of a VB.NET class project named RssGen and a test app to drive the RSS generator assembly. RssGen contains a pair of classes: Rss and RssItem. Rss is responsible for the header and channel elements, and it contains a collection of RssItem objects. You normally call RssGen from a data access routine to regenerate your RSS output file with new data at some appropriate interval. In a typical usage scenario, you create a new Rss object, add available items using the overloaded AddItem methods, then call SaveFile to write the RSS file to disk. Download the sample object and follow along.

Create the RSS Generator Component
Fire up Visual Studio .NET and create a Class Library project named RssGen. Delete the default Class1.vb file from the project and add a new class named Rss.vb. Add Imports statements at the top of the file for namespaces you'll need in the code:

Imports System.IO   
Imports System.Text 

Add a second class within Rss.vb named RssItem below the Rss class (you can also put RssItem into a separate class file in the project). Create public string variables within RssItem for the RSS item elements you'd like to support—for example, Title, Link, Description, Author, PubDate, and Guid. Guid is a unique value used by many RSS reader applications to determine whether a content item has changed and therefore should be redisplayed. Change the Guid value if you change the content of an item and want the client display app to show a new item.

The RSS spec says you must either provide Title and Link or Description for an RSS item. Add two class constructors; the first takes Title and Link parameters, and the second takes only a Description parameter:

Public Sub New(ByVal TitleInit As _
  String, ByVal LinkInit As String)
	Title = TitleInit.Trim
	Link = LinkInit.Trim
End Sub
Public Sub New(ByVal DescriptionInit _
	As String)
	Description = DescriptionInit.Trim
End Sub

Set the Author, PubDate, and Guid values in the calling app as class properties. You can implement many other optional properties in your component.

RssItem has one method named WriteXml that returns the XML elements for each property you set in the item:

Public Function WriteXML _
	(ByVal Indent As Integer) As String
	Dim sb As New StringBuilder(1024)
	sb.Append(WriteElement("item", _
		Indent))
	If Title.Trim.Length > 0 Then
		sb.Append(WriteElement("title", _
			Title, Indent + 1))
	End If
	'...emit other properties here
	sb.Append(WriteElement("/item", _
		Indent))
	Return sb.ToString
End Function

Pre-allocate a large buffer for the StringBuilder object rather than use string concatenation to avoid expensive memory allocations when you build long strings. The Indent parameter helps create human-readable XML in the RSS output file.

The WriteElement function is overloaded to handle elements both with and without values (such as <item> and <title>value</title>). WriteElement handles tag indention and character encoding in element values that would be illegal in the XML file. For example, elements such as Description and Link often contain HTML tags with embedded URLs that use the characters "<", ">", and "?":

<a href="http://site/page.asp?val=xyz">

Encoding replaces these special XML characters with "<", ">", and "&", respectively, so the RSS data values containing the HTML markup validate as well-formed XML.

Combine RSS and RssItem Classes
Add private variables in the Rss class, and create read-only property procedures for the RSS filename and the Title, Description, and Link elements for the Channel section of the RSS file:

Private m_sTitle As String 
Public ReadOnly Property Title() _
	As String
	Get
		Return m_sTitle
	End Get
End Property

You initialize these four class member variables through parameters to the Rss class constructor. The property procedures are read-only because you won't change these values after creating the class. Finally, add a private class variable to store the RSS Items collection:

Private mhtRSSItems As New Hashtable

VB.NET still supports the classic VB Collection object, but you should use native .NET objects such as Hashtable instead because they're more flexible and work the same across the .NET languages.

Create a pair of overloaded AddItem methods that call the RssItem constructors you created earlier (the second one takes Title and Link as parameters):

Public Function AddItem(ByVal _
	Description As String) As RssItem
	Dim oItem As New _
		RssItem(Description)
	mhtRSSItems.Add _
		(mhtRSSItems.Count + 1, oItem)
	Return oItem
End Function

Finally, create the RSS output file with the SaveRSS method. SaveRSS overwrites the output file if it exists already. No file is written if the directory doesn't exist or there's an output error:

Public Function SaveRss() As Boolean
If m_sFileName.Length > 0 Then
	If Directory.Exists _
	 (Path.GetDirectoryName _
	 (m_sFileName)) Then
		If WriteFile(msRSSHeader & _
			msRSSChannel & OutputItems() _
			& msRSSFooter) Then
			Return True
		End If
	End If
End If
	Return False
End Function

The OutputItems method loops through the mhtRSSItems collection calling the RssItem.WriteXML method on each item and adding it to the output string:

Private Function OutputItems() _
	As String
	Dim item As Integer
	Dim sb As New _
		StringBuilder(1024)
	For item = mhtRSSItems.Count _
		To 1 Step -1
		sb.Append(Ctype _
		(mhtRSSItems.Item(item), _
		RssItem).WriteXML(2))
	Next
	Return sb.ToString
End Function

The For loop iterates in reverse order so the newest item goes into the file first and the oldest item is at the end of the Item list.

The WriteFile method called from SaveRSS uses a StreamWriter object to create the output file:

Private Function WriteFile _
	(ByVal Contents As String) _
	As Boolean
	Dim sw As StreamWriter
	sw = New StreamWriter(m_sFileName)
	sw.Write(Contents)
	sw.Close()
	Return True
End Function

Error handling is omitted from WriteFile for brevity, but the file isn't written and WriteFile returns False if an error occurs.

As you can see, creating an RSS feed is straightforward. You'll want to add optional Channel and Item elements and more complete error handling for your own applications. You can also create categories for your items, but I don't cover that in this sample.

Test Your Component
The sample code also contains a WinForms project named RssGenTest that illustrates how to use the RSS component (see Figure 1). You fill out the fields and click on Publish to create an RSS feed file. Examine the file contents in a text editor to see how the < and > characters in the sample item's Description field are encoded as < and >. Click on the Clear Item button, add new fields, and click on Publish again. Reload the file in the text editor to see how the newest item is listed at the top of the Item list—exactly what you'd expect to see in your newsreader application.

Direct the output of your test app to a virtual directory on your Web server, and point your favorite newsreader at the output file's URL. You'll see any new items in the output list each time you republish the file and refresh the newsreader. In a real-world application, your users might use a newsreader or consume your RSS feeds within another app such as an intranet portal or a custom smart-client app.

Although RssGenTest creates the RSS feed manually, you'll usually call RssGen from within a data generator application that can write files to your Web server. You need to decide how many items you want to have in the feed, limiting the output by date or at a certain item count. Rather than creating logic to figure out what new data you have and adding it into an existing file, RssGen requires that you re-create the entire output file each time.

The process of creating an RSS file is straightforward, and you can use the RssGen component to start generating your own RSS feeds. You can use feeds for a variety of purposes within your organization, from internal data and status reporting to publishing product information changes and Web site updates to your external customers. RSS is a powerful addition to your programming toolbox that'll pay dividends as you begin exploring and applying this useful technology.

comments powered by Disqus
Most   Popular