My move from using cfhttp and rssatom.cfc to cffeed.
For the last year or so, I had been using cfhttp and rssatom.cfc to read and parse rss feeds so that I could display the content on a site running on ColdFusion 7. I recently upgraded the server to ColdFusion 9, but shortly afterward started to receive the error, "An error occurred while Parsing an XML document. Content is not allowed in prolog". The error was not consistent, but occurred twenty to thirty times a day. I figured it was a good time to move to the more current cffeed tag that became available in ColdFusion 8 and see if it would resolve the issue.
The move to cffeed was painless and the tag really makes consuming feeds really easy. I had to adjust my output as the structure outputted from cffeed was different than the structure outputted from rssatom.cfc. One issue I did run into was with the post date which was stored in the updated key of the entry structure. The datetimestamp was stored as in iso8601 format and could not be outputted with the ColdFusion dateformat function. After a little searching, I found the DateConvertISO8601 UDF at CFLib.org that formatted the date as an ODBCdatetime stamp which I could use with the dateformat function.
The final piece to this was the fact that I needed to display different items in the feeds at different places on my site. We show the most recent blog post on our homepage and the most recent post from different columns on specific sub pages within the site. This was accomplished by looping through the structure and finding posts that have a specific term key within the category struct.
Here is an example of the code used to display a blog post from a specific column in a blogger feed:
Read in rss feed and cache contents for an hour.
<cfset feedurl = "http://blog.example.org/feeds/posts/default">
<cfset cacheMinutes = 60>
<!--- check if cached, and not too old --->
<cfif not structKeyExists(application,"feedcache") or dateDiff("n", application.feedcache.created, now()) gt cacheMinutes>
<cffeed source="#feedurl#" name = "feeddata_blog" timeout="20">
<cfset application.feedcache = structNew()>
<cfset application.feedcache.feeddata_blog = feeddata_blog>
<cfset application.feedcache.created = now()>
</cfif>
include DateConvertISO8601.cfm template to load UDF.
<cfinclude template="DateConvertISO8601.cfm">
Loop through the feed struct and find the specific column that needs to be displayed.
<cfif StructKeyExists(application.feedcache.feeddata_blog.entry[1].category[1], "term")>
<cfset keyList = Structkeylist(application.feedcache.feeddata_blog.entry[1].category[1])>
<cfset keyList = ListSort(keyList, "TEXT")>
<cfelse>
<cfabort>
</cfif>
<p>
<div id="blog">
<cfset item = 0>
<cfloop index="i" from="1" to="#ArrayLen(application.feedcache.feeddata_blog.entry)#">
<cfif application.feedcache.feeddata_blog.entry[i].category[1].term eq 'Column B'>
<cfset item = #i#>
<cfbreak>
</cfif>
</cfloop>
<cfoutput>
<div class="capsblue">
<a href="#application.feedcache.feeddata_blog.entry[i].link[1].href#" target="_blank" class="text">#ucase(application.feedcache.feeddata_blog.entry[i].link[1].title)#</a>
</div>
<cfif application.feedcache.feeddata_blog.entry[item].category[1].term IS NOT "">
<div class="copy">#application.feedcache.feeddata_blog.entry[item].category[1].term#</div>
</cfif>
<cfif application.feedcache.feeddata_blog.entry[item].author[1].name IS NOT "">
<div class="copy">#application.feedcache.feeddata_blog.entry[item].author[1].name#</div>
</cfif>
<cfset sDate = application.feedcache.feeddata_blog.entry[item].updated>
<cfset ts = #DateConvertISO8601( sDate, 0 )#>
<cfif isDate(ts)>
<div class="copy">#dateformat(ts, "full")#</div>
</cfif>
<p align="left">#application.rsscachetours.feeddata_tours.entry[item].content[1].value# <a href="http://example.org/search/label/Column%20B">Read more ...</a>
</p>
</cfoutput>
In the end, I'm no longer getting the original error and I'm displaying content from the feed with less code and complexity.