BeaverBlogg

April 24, 2007

Displaying an RSS feed using XMLDom and ASP

Filed under: ASP, Articles, XML — Karl @ 3:21 pm

It happened again. I saw some really horrible examples today on how to show an RSS feed using XMLDom so I took another trip with the WayBackMachine to try to dig this article up. After figuring which id-number this post had on the old installation it wasn’t that hard.

Anyone remembered why I wrote this article the first time? Here is a quote from the original about why I wrote it.

Imagine a script that selects all nodes (XPath query was something like “//*”), not caring where in the document, then looping them thru looking at their names and guessing what they are and then adding them to four separate strings with some weird separator. After doing this, they split the strings into four arrays and started looping out the content. Oh please, it was horrible. No real sense of XML at all I’m afraid . I know there are better resources then that on the net, but I still felt I had to contribute with just one more.

Hopefully there are still people who need to learn this out there so I didn’t waste my time recovering it. Anyway, let’s get going

If you never heard of RSS earlier, you are either very ignorant to what happens on the web these days and/or you are stuck running Internet Explorer which lacks any built in support for it. It all comes down quite easy though. An RSS feed is an online news syndication in the XML format. The main idea is to have a standardized way to share news over the net. I for an instance offers my articles as an RSS feed so people easily will know when I’ve written something new. For those who want to dive deeper into RSS I would recommend “What Is RSS” over at XML.com.

I thought that it might also be a good idea to show a short RSS feed with only one news item in it so you know what source we are working with.

This is a quite minimal feed document. It could have any number of “item” nodes aswell as it could have way more descriptive tags both for the channel and for the items. This is not how the feed for my site looks. I’m using a nice tool that generates everything for me and puts in 10 or 15 extra tags that are far from necessary. I feel that it would be quite an overkill to start out with that and I doubt that more then 5% of the RSS readers out there actually cares about all those tags anyway.

Anyway, lets get going. For those who have read my previous tutorials, there isn’t anything really new here, for those who haven’t, I would recommend reading XML, XMLDom and ASP Part 1 and XML, XMLDom and ASP Part 2.

So lets start examining the code then.

This part is very almost a carbon copy of the first lines in my second article, I just added nodeCol, oNode, oChildNode and i to the variable declaration and set the async property to false. The async property tells if the dom should proceed in asynchronous or synchronous mode. Since we don’t want it to continue to execute without being done with the HTTP request, we set it to false (synchronous mode).

Next, we have a simple if statement to see if the document has a documentElement (root element, remember?). If not, we show a short error message.

If the script got this far, we probably got our RSS feed without any problems. Now we call the selectNodes function to select all item nodes from the feed and put the collection in nodeCol. Then, we do a simple for-each loop to go through all the nodes in the collection.

This might seem like a long chunk of code, but it’s quite repetive so I think you can handle it. First of all, we write some standard html markup. We encapsulate each item in a paragraph. Next, we try to select a childnode from the current node. Each item should have a title, a pubdate, a description and a link, but since people are lazy sometimes they leave one or several of them out so to make this as general as possible we make sure that the nodes exists to avoid a crash. Anyway, we try to selet any childnode named title and put it into the oChildNode variable. Then, if not oChildNode is nothing, we can ouput the text content of that node by using oChildNode.text. Again we are adding some markup to the code, this to make it easy to style it afterwards using CSS. We repeat the exact same thing for the other “supposed to be there” nodes and print them out accordingly. We even make a link out of the link node if it exists. And well, thats kinda it.

This post didn’t take long to write so I apologize if it contains any errors of some sort. If it do, then please tell me so I can correct them as fast as possible. It was quite fun though to join the stuff I’ve written about in the first to articles into this one and there will be more to come!

April 9, 2007

XML, XMLDom and ASP, Part 2

Filed under: ASP, Articles, XML — Karl @ 10:34 pm

This is the second article in my series about XML, XMLDom and ASP. For those who missed the first it’s available here

In my first article I showed how to parse an XML document using XMLDom and displaying the data. In this second tutorial I’ll show two different ways to retrieve an XML document from a remote server using ASP and ServerXMLHTTP.

XML is a great way to share information. However, if you want to be able to share it people will need to retrieve the data from you somehow (or you from them). For this purpose we have an object called XMLHTTP or, if used on a server, ServerXMLHTTP. Since both XMLDom and XMLHTTP are part of MSXML2 they can cooperate very nice. XMLDom can by auto use XMLHTTP to retrieve information and if you use XMLHTTP it can by auto return a XMLDom object with the retrieved XML data.

The easiest way to retrieve XML from an external site is to let the XMLDom handle it all. This requires the least amount of code and I would guess that it’s also a tiny bit more effective resource wise. Here is how to do it:

This code is really simple so I’ll describe it all in one chunk. First we declare the variable and create the xmlDom object. This is precisely as we did in the first article so far. Next we call the setProperty method to specify that it should use the “ServerHTTPRequest” feature. By specifying this we are able to pass an URL to the load method which we do on the next line. In this example it will load my RSS feed into the xmlDom.

This might seem like a great solution since it’s so simple, however it has some drawbacks. First of all, if the URL is unavaible, it will throw an error. Aswell as if the loaded data isn’t wellformed xml, it will throw an error. So to be sure that this code doesn’t throw an nasty error on your visitors you would have to extend it with some error handling.

There we have it, some basic error handling to see if it loaded or not. I expect that people know at least some about error handling in ASP. If not, then write a comment about it and I make take it up a bit more in an later article.

The other way to go to retrieve external information is to manually create the ServerXMLHTTP object and making it browse to the URL and return it’s contents. This requires a bit more code, but it also has some other nice features. For example, it can post data to the remote server, it can retrieve other data then just xml like a binary file or a simple text document. I will start by creating the same example as I did previous in this article using ServerXMLHTTP.

This made for a whole extra line to the code if compared to the original earlier in this post. This one isn’t much harder to understand then the previous one. We declare the variables, we create the ServerXMLHTTP object and then we call the Open method of the xmlHttp object. This method takes two arguments, first one is a string which describes the HTTP method to use. GET is fine unless you need to post data which you mostly won’t do. The second argument is the URL to retrieve the data from and again we use my RSS feed. After that we call the Send method which will trigger the object to browse to our URL and fetch the data. The Send method takes one optional argument which is the data to send to the URL. When using GET as method this has no real function. Last in the script we retrieve an xmlDom from the responseXML property of xmlHttp.

That wasn’t to bad was it? Though it isn’t ever as simple as it seems. If you are browsing to a url that doesn’t return “text/xml” as content type the responseXML property will be empty so we will need to add some error handling to that as well. Also, if you take the URL as a dynamic parameter and it doesn’t contain a valid URL or the URL is unavaible it will throw an error. So lets add the same as in the previous example here aswell and add some stuff to it.

I know, it’s a mess. But it covers all problems that can arise and provides specific error messages for the different ones. I have to admit, I never go this far in error handling but I still want to show what that can be done and what to look for.

After calling the Send method it might be an good idea to check the error object. If something failed miserably it probably was here.

After that it can always be an good idea to have a look at the status property to see what HTTP response code it returned. It it wasn’t 200 (HTTP 200 OK) we don’t want the data. Other usual statuscodes are 404 (File not found) and 500 (Internal server error) so those who want it really nice can check for those aswell and output it to the user.

Last we check if there is a responseXML object avaible. If it isn’t, then the server returned an invalid response (and might be caught already but not for sure).

There we have it, two different approaches to retrieving XML from an external source. There is however one more thing I would like to talk about. In this article I’ve used the ServerXMLHTTP object. When asking my good friend Google about retrieving external data using ASP I found several articles telling the readers to create the “Microsoft.XMLHTTP” object or “MSXML2.XMLHTTP.4.0″. This will work on your ASP page, but it’s not a very good idea to use. They were created for use in a client environment, not to be executed by a server. They rely on winsock (or some other client side communication layer, can’t remember exactly which, sorry) instead of winhttp which is used for server applications. Being built as clientside objects they also use the current proxy settings from Internet Explorer which might not always be desirable. I will get back to these objects in a later article when I start to talk about Ajax development which works with these objects using clientside JavaScript.

I haven’t decided yet what to write about in Part 3 to be honest. It will be XML for sure, but I’m not sure if I will go for simple XSL stylesheets or creating new documents using xmlDom only. Tune in for my next article and we’ll see what it contains :) .

XML, XMLDom and ASP, Part 1

Filed under: ASP, Articles, XML — Karl @ 10:30 pm

Everyone who works with the web these days know what XML is, but how many know how to really use it? Over the past months I’ve seen lots of people using regexps to parse XML as text strings and people trying to use the XMLDom in ASP and failing miserably. They just look at me like I’m stupid or something when I try to mention XPath as the correct way to go and kindly explain that they use XML, not XPath. I’ve been working with XML and XMLDom for over a bit over a year now and I feel really comfortable with it. It can do just about everything I want it to.

Here is a quite typical XML document. It contains a root element, a description tag and a collection of files.

Thats the way I like to have my XML. As much as possible as attributes. Some people seem to prefer this type though:

This is easier to understand for a beginner maybe but it’s not as easy to work with as the first data.

Anyway, lets try to get some data out of this. Lets imagine that the XML data is avaible in a filed called Data.xml in the same folder as the script. I’ll concentrate on the first XML example to start with.

The output of this would look something like this:

Description: Files attached to subject 1
File: beaver.jpg (12432 bytes)
File: beaver2.jpg (53174 bytes)

File: beaverfarm.doc (162475 bytes)

Not to shabby if you ask me. Lets take a quick stroll through the code now.

This part kinda explains itself. Declare the variables we are going to use. Then create the XMLDom object. We expect the data to be in a file called Data.xml in the current folder so we use Server.Mappath to get the absolute path to it and then calls .load from the XMLDom to load the data.

Then to be sure that there was no problems with the loading we check that the parseError property of the XMLDom is 0. If it isn’t something is wrong with our XML data and we show an error and quit.

The second part might be a bit harder to understand. First, we check if xmlDom.documentElement is nothing. If it is we throw an error and end the execution of the script. The documentElement of a XML document is the root element. In our case, the <root> tag. Every XML document needs one and only one root element. It can be named anything however so <root> isn’t a mandatory name, I just like to use it. If xmlDom.documentElement is nothing then it’s most likely that Data.xml was just an empty file. The XMLDom could parse the data without problems since there wasn’t anything to parse so this is a good thing to look for.

Next we try to read out the description element by using a XPath query. The function used is called selectSingleNode() and will return one single node (just as it’s name says) from the specified XPath query. It is avaible on any node in the document and works with relative XPaths. My XPath query is very simple and states that I want the node called “description”. I call the procedure from the documentElement node so I don’t have to write “root/description” which is it’s real path. Calling xmlDom.selectSingleNode(”root/description”) would return the same result.

After selecting the node and puttings it’s reference in the oNode variable we make an if-statement to see if it returned an object. If oNode is nothing then there wasn’t any node called “description” at the specified place in the document. If it isn’t nothing, then we expect that we got the right now and print it out using it’s .text property.

Not much left now. Here we use another procedure called selectNodes(). Like selectSingleNode() this procedure is avaible on all nodes and uses an XPath query to specify which nodes that we want. The main difference is that selectNodes() returns a collection of nodes instead of a single one.

The XPath query this time specifies that we want all “file” nodes under “files”. Not to hard to understand this one either. We put the reference to the collection in the nodeCol variable.

Next we initiate a for-each loop to go through all the nodes in a simple manner. We write out some markup (HTML) to make it look good. First we create a <span> tag with a title attribute in which we put the file description. Every node has a function called getAttribute() which takes one parameter with the attribute name. It returns an empty string if the attribute was not found and if it exists it returns the value. We make sure to HTMLEncode the value since we might not know what text is in the attribute and we don’t want anything that breaks our markup do we?

We end the opening <span> tag and write out the filename. We also add a paranthesis with the filesize in bytes. All using the .getAttribute function. Then finallyl we close the <span> tag and add a linebreak before the next file.

This is the way I like it to be done. If I got to shape the XML it would be as much as possible in the attributes and as few element nodes as possible. But since I don’t get to chose XML in all cases I still get suck with the second XML example some times. Here is how the code to produce the same output would look using that source data.

Not much happened there until the last block. Now I have to use selectSingleNode() to get the subnodes (child nodes) and look at their text property to get the values out. This might not seem like a great problem but most people get tired of havings lots and lots of element nodes after some time.

XPath is a quite powerful query language. You can specify in quite detail what nodes you want. For example, if I only want files that are smaller then 100kb I could just change a bit in the script to this:

Adding [] after a node tells that I want to evalutate something. The @ before “size” denotes that I want to look at an attribute node. It’s quite easy to understand for most. If I would like to do this using the second example the query would look like this:

This has been a brief introduction to working with the XMLDom in ASP aswell as making some simple XPath queries. It is also my first serious blogg post ever written so I hope someone finds it interessting. It was written in one evening without testing any of the code. Next time I’ll dig a bit deeper into XPath and show how you can retrieve XML data from an external websource using XMLHTTP.

Powered by WordPress