Processing RSS Feeds

Contact Us or call 1-877-932-8228
Processing RSS Feeds

Processing RSS Feeds

RSS stands for Really Simple Syndication. It is an XML format for making news items or other bits of content readily available. There are different versions of RSS, but all of them contain <item> elements for holding the different news items. These <item> elements at their simplest have the following structure:

<item> <title>Item Title</title> <link>http://www.webucator.com/link/to/full/article</link> <description>Item description. Sometimes contains escaped HTML characters.</description> </item>

There are other elements that the <item> element can contain, but for our purposes, we'll keep it simple and assume that an RSS document is made up of one or more <item> tags structured as shown above. We will ignore all other elements.

There are several ways to process RSS feeds. Through code samples, we will see how to do it using XmlSearch() and XmlTransform() with XSLT. The output of the pages will look like this:

Processing RSS Feeds with XmlSearch()

Code Sample:

XML/Demos/RssFeed.cfm
<html>
<head>
<title>RSS Feed</title>
</head>
<body>
<cfparam name="FORM.rssURL" default="http://rss.news.yahoo.com/rss/topstories">

<cfoutput>
<form method="post">
	<input type="text" size="50" name="rssURL" value="#FORM.rssURL#">
	<input type="submit" value="Get Feed">
</form>

<cfset rss = XMLParse(FORM.rssURL)>

<cfset items = XMLSearch(rss, "//*[local-name()='item']")> 

<cfloop index="i" from="1" to="#ArrayLen(items)#">
	<cfset title = XMLSearch(rss, "//*[local-name()='item'][#i#]/*[local-name()='title']")>
	<cfset title = title[1].xmlText>
	
	<cfset description = XMLSearch(items[i], "//*[local-name()='item'][#i#]/*[local-name()='description']")>
	<cfset description = description[1].xmlText>
	
	<cfset link = XMLSearch(items[i], "//*[local-name()='item'][#i#]/*[local-name()='link']")>
	<cfset link = link[1].xmlText>
	
	<div style="width:600px">
		<h2 style="clear:both;padding-top:10px; border-top:1px solid blue;">#title#</h2>
		<div style="border:1px solid black; padding:4px; width:90%; margin:10px;">#description#</div>
		<div style="float:right; width:20px; margin-bottom:10px; ">
		<a href="#link#">Read</a>
		</div>
	</div>
</cfloop>
</cfoutput>
</body>
</html>

This file parses an RSS feed from a URL and creates an XML document object:

<cfset rss = XMLParse(FORM.rssURL)>

It then creates an items array containing all nodes that have the local name "item". By using the local name, we avoid the headache of namespaces. You can read this XPath as "any element descending from the root whose local name is 'item'."

<cfset items = XMLSearch(rss, "//*[local-name()='item']")>

It then loops through the items array grabbing the title, description and link nodes, assigning their XmlText to variables, and outputting the results in a div.

<cfloop index="i" from="1" to="#ArrayLen(items)#"> <cfset title = XMLSearch(rss, "//*[local-name()='item'][#i#]/*[local-name()='title']")> <cfset title = title[1].xmlText> <cfset description = XMLSearch(items[i], "//*[local-name()='item'][#i#]/*[local-name()='description']")> <cfset description = description[1].xmlText> <cfset link = XMLSearch(items[i], "//*[local-name()='item'][#i#]/*[local-name()='link']")> <cfset link = link[1].xmlText> <div style="width:600px"> <h2 style="clear:both;padding-top:10px; border-top:1px solid blue;">#title#</h2> <div style="border:1px solid black; padding:4px; width:90%; margin:10px;">#description#</div> <div style="float:right; width:20px; margin-bottom:10px; "> <a href="#link#">Read</a> </div> </div> </cfloop>

Processing RSS Feeds with XmlTransform()

The XmlTransform() function can be used in conjunction with an XSLT to process RSS feeds. The file below shows a very basic XSLT that will transform an RSS feed to output HTML very much like we saw in the last example.

Code Sample:

XML/Demos/rss.xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dc="http://purl.org/dc/elements/1.1/" version="1.0">
	<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
	<xsl:template match="/">
		<xsl:apply-templates select="//*[local-name()='item']"/>
	</xsl:template>
	<xsl:template match="//*[local-name()='item']">
		<div style="width:600px">
			<xsl:apply-templates select="*[local-name()='title' or local-name()='description']"/>
		</div>
	</xsl:template>
	<xsl:template match="*[local-name()='title']">
		<h2 style="clear:both;padding-top:10px; border-top:1px solid blue;">
			<xsl:value-of select="."/>
		</h2>
	</xsl:template>
	<xsl:template match="*[local-name()='description']">
		<div style="border:1px solid black; padding:4px; width:90%; margin:10px;">
			<xsl:apply-templates />
		</div>
		<div style="float:right; width:20px; margin-bottom:10px; ">
			<a href="{parent::*[local-name()='link']}">Read</a>
		</div>
	</xsl:template>
</xsl:stylesheet>

Code Sample:

XML/Demos/RssFeed-xslt.cfm
<html>
<head>
<title>RSS Feed</title>
</head>
<body>
<cfparam name="FORM.rssURL" default="http://rss.news.yahoo.com/rss/topstories">
<cfoutput>

<form method="post">
	<input type="text" size="50" name="rssURL" value="#FORM.rssURL#">
	<input type="submit" value="Get Feed">
</form>

<cfset rss = XMLParse(FORM.rssURL)>
<cfset result = XmlTransform(rss,ExpandPath("rss.xsl"))>

<cfset resultFixed = Replace(result,"&gt;",">","ALL")>
<cfset resultFixed = Replace(resultFixed,"&lt;","<","ALL")>
#resultFixed#
</cfoutput>

</body>
</html>

Again we start by parsing an RSS feed from a URL to create an XML document object:

<cfset rss = XMLParse(FORM.rssURL)>

We then transform the document against our XSLT:

<cfset result = XmlTransform(rss,ExpandPath("rss.xsl"))>

Because some RSS feeds include escaped HTML characters in the description, we use the Replace() function to unescape these characters.

<cfset resultFixed = Replace(result,"&gt;",">","ALL")> <cfset resultFixed = Replace(resultFixed,"&lt;","<","ALL")>

Finally, we output the result:

#resultFixed#
Next