ASP (VBScript) RSS reader/writer class
Once i was looking for a nice RSS class/component for ASP which allows me to read all kind of feed formats programmatically. In addition to the correct parsing it should also be able to create own feeds for publishing purposes. Unfortunately I could not find any component which fits those requirements in ASP and therefore written my own.
Due to the different versions of RSS (0.91, 0.92, 1.0, 2.0, etc.) and formats like ATOM it was not really easy to parse them all within one component. I needed to find the least common denominator which consists of the basic elements like feed title, feed description, feed published date, the feeds language and it published items. The items on the other hand must hold at least title, description, category, author, link and published date. This metadata is available but its occurrence is a bit different in e.g. ATOM and RSS. The component I have written consists of two VBScript classes (RSS and RSSItem) which supports the following features (download and documentation is at the bottom):
- Reading all kind of RSS formats (RSS 0.91, 0.92, 0.94, 1.0, 2.0 and ATOM)
- Generating own feeds as RSS 2.0 (with UTF8)
- Generation can be done directly into a file
- XSLT can be applied to the feed
- Feeds can be cached for a given amount of time (all visitors share the same cache).
- Timeout for the request can be configured. (if server not responding, etc.)
- Supports the simple Dublin Core elements (http://www.dublincore.org/)
- easy to use programmers interface
Before I keep going with the examples of how to use the class(es) here is a link to a demo I have quickly created on my ASP server. Play around and check if your feeds are being correctly recognized by the component.
Could the component parse your feed? If not please let me know so I can improve it. However, lets check how we use this tool. The following example creates an instance of the RSS class, requests the feed and loads all its information into the class' properties. The title of the feed is written to the response:
-
<!--#include file="RSS.asp"-->
-
set r = new RSS
-
r.url = "http://syndication.thedailywtf.com/TheDailyWtf"
-
r.load()
-
if r.failed then
-
response.write("Could not load the feed.")
-
else
-
response.write(r.title)
-
end if
Interesting thing here is the failed property. Whenever a feed is requested it is necessary to check the failed property if the request has failed or not. If it failed it means that the feed could not be recognized as a valid (supported) feed, the server is not responding, the url does not exist, or the XML could not be parsed (and therefore is invalid). As we are requesting data from a kind of "untrusted" source it is a nice feature to display our user that the feed is currently not available. If the load was a success all properties are populated with the feeds data. Iterating through the items of the previous example looks the following:
-
for each item in r.items.items
-
response.write(item.title)
-
response.write(month(item.publishedDate))
-
next
Those lines iterate through the items (items is a dictionary which holds objects of type RSSItem). Nice feature here is that the date has already been converted into a VBScript date type and can be used within all date functions. In this example the month of the date is written out.
With this concept it is easily possible to request feeds and process them programmatically. E.g. storing them into the database, etc.
Using the cache
-
<!--#include file="RSS.asp"-->
-
<!--#include file="Cache.asp"-->
-
set r = new RSS
-
r.url = "http://www.webdevbros.net/feed/"
-
r.setCache "h", 1
-
r.load()
-
if r.failed then
-
response.write("Could not load the feed.")
-
else
-
response.write(r.description)
-
end if
Caching can be turned on with the "setCache" method which requires the type of interval and the interval value (in the example 1 hour). This feed is stored now within the cache (see Caching class for ASP) on the server for 1 hour before it is requested again. All users share the same cache which means that only the first user will recognize the request and the others will already get it from the cache. The RSS class supports caching but it requires the Cache class for this feature. Just download it and include it like in the example.
Using XSLT for the feed
-
<!--#include file="RSS.asp"-->
-
set r = new RSS
-
r.url = "http://www.webdevbros.net/feed/"
-
r.draw("stylesheet.xsl")
-
if r.failed then response.write("Could not load the feed.")
If you have your own XSL file for your feeds you can apply it with the draw() method. It grabs the feed, applies the given stylesheet and prints out the result to the response. As you can see there is again this check for the failed property. That is necessary because the same errors as with the load() method could happen. Additionally the transformations could have failed. It is also possible to use caching here, just as described before.
Generating an own feed (RSS 2.0)
-
<!--#include file="RSS.asp"-->
-
set r = new RSS
-
r.title = "Freaky funky feed (FFF)"
-
r.description = "another source for nonsense :)"
-
r.publishedDate = now()
-
r.language = "en"
-
set it = new RSSItem
-
it.title = "My first blog entry"
-
it.description = "i am so freaky and can do <strong>html</strong>"
-
it.publishedDate = dateAdd("d", -2, now())
-
it.author = "f. freak"
-
r.addItem(it)
-
r.generate "RSS2.0", "/rss.xml"
This example generate a simple feed with one item. As you can see its necessary to use the RSSItem class. The generate() method generates a feed into a file called rss.xml. The method also returns the generated xmldom if you prefer to store the feed in a different way. E.g. you could output directly to the response with:
-
r.generate("RSS2.0", empty).save(response)
Another example for the generation grabs an existing feed (in this case ATOM) and generates an RSS 2.0 version. Its somehow a tranformation which is therefore possible .. a nice side effect.
-
<!--#include file="RSS.asp"-->
-
set r = new RSS
-
r.url = "http://www.webdevbros.net/feed/atom/"
-
r.load()
-
if not r.failed then r.generate "RSS2.0", "/rss.xml"
There is nothing to say more now :) Have fun with this component and feel free to use it. Just keep my credits ... I am looking forward to any enhancements from you guys and to the feedback. I am not an expert on feeds and therefore you might have some suggestions, improvements, etc.
Greetings from vienna.
Download RSS 1.0
RSS 1.0 Documentation
DEMO
NOTE: RSS class is part of the ajaxed library now!
check ajaxed library for a newer version...


(9 votes, average: 4.33 out of 5)
July 6th, 2007 at 4:21 pm
Hi Michal, thanks for this, im getting an error:
Microsoft VBScript runtime error '800a01a8'
Object required: 'lib'
/RSS.asp, line 163
Any ideas?!
Sam
July 7th, 2007 at 9:29 pm
hi sam, this class is extracted from my framework which also includes the possibility to throw custom errors. This error comes up because the class wants to call the throwError function which it cannot find. Just take a look into the line where the error is thrown to see the reason. In your case its "lib.throwError("Title, Link and description are required.")". This means that if you want to generate a feed it is necessary to set the properties title, link and description of the feed.
August 9th, 2007 at 3:34 pm
Hi Michal,
I've tried making the url field into an array to make the tool aggregate rss feeds into one giant list. The issue I'm having is that the items collection seems to reset with each rss feed. Here are my modifications to the load function ... do you know what else I would need to change to have this functionality work? - Thanks for anything.
if theCache is nothing then
for each address in url
loadXML(getXMLHTTPResponse(address))
next
else
for each address in url
if address "" then
cacheID = address & "|LOAD"
cachedItem = theCache.getItem(cacheID)
if cachedItem "" then
'the cache for this method stores the data as xml and needs to be parsed again
loadXML(cachedItem)
else
'load and save to cache
xmlResponse = getXMLHTTPResponse(address)
loadXML(xmlResponse)
theCache.store cacheID, xmlResponse
end if
end if
if failed then exit sub
select case getRSSType()
case "RSS1.0"
readRSS("1.0")
case "RSS2.0"
readRSS("2.0")
case "ATOM"
readATOM()
end select
next
end if
August 12th, 2007 at 7:04 pm
@john: why dont you just create an instance for each feed an merge the items together? for this you dont need to change any of the code...
September 20th, 2007 at 12:04 am
Excellent work Michal. Now I just have to decide if I want to load the rss data into a db table for further "searching/filtering" or just slap the data into an array and do an old fashioned "do loop" for searching/filtering.
This is almost EXACTLY what I was looking for (I did NOT want to write it myself...gotta love GOOGLE, a lazy man's paradise!)
Thanks again!
September 20th, 2007 at 12:07 am
John, to make a giant list I'll define an array and simply call a new rss for each source I want (looping thru each and loading in my array). From there I'll call the array for the actual data.
March 14th, 2008 at 12:53 pm
as to set up to 5 number the items es. iMaxResults = 5 items
dany bay
March 31st, 2008 at 3:40 pm
Hy all,
To fix "lib.throwError" problem just add the following code in rss.asp:
public ErrMessage ''[string] Error Message
private Sub libthrowError(str)
ErrMessage = str
Response.Write ErrMessage
end sub
and then find & replace lib.throwError with libthrowError in the file...
April 15th, 2008 at 8:55 am
[...] ajaxed has the right component inside. There is a full detailed article about this component here. PLAIN TEXT [...]
May 15th, 2008 at 11:21 am
Hello Michel,
I'm using my own RSS class at the moment, but would like to have one that can handle more feed type, like your.
But when I tested one of my important feed-links in your demo page it failed.
I don't know German but it looks like it's having problems extracting the field.
Can you please have a look at this and email me back?
Here is the feed: http://rss.bowlingdigital.com/bowling/?q=node/feed
BRG Reine
May 15th, 2008 at 11:22 am
I noticed that my xml tag was stripped in the last post...
I don't know German but it looks like it's having problems extracting the pubDate field.
May 15th, 2008 at 12:05 pm
reine i have to take a closer look into it .. but as i have recognized also IE does not recognized this feed. google reader does :)
i will look into it. thanks for your feedback
May 26th, 2008 at 8:45 am
Michal, how is it going, have you found any solution to my problem?
June 18th, 2008 at 11:27 pm
Is this open source? In the code it says "see license.txt in the root" but there's no such file in the .zip
June 19th, 2008 at 3:24 am
yeah it totally is ... you cannot find the license.txt because i have extracted the component from the ajaxed library .. just a small mistake. you might want to check the ajaxed library http://www.webdevbros.net/ajaxed/