Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

RSS and AJAX: A Simple News Reader
by Paul Sobocinski | Pages: 1, 2, 3, 4, 5

Displaying the RSS Data: The showRSS(RSS) Function

Before we go into the JavaScript code for the showRSS(RSS) function, let's have a look at the root div element of the HTML page mentioned earlier:

    <div class="rss" id="chan">
        <div class="rss" id="chan_title"></div>
        <div class="rss" id="chan_link"></div>
        <div class="rss" id="chan_description"></div>
        <a class="rss" id="chan_image_link" href=""></a>
        <div class="rss" id="chan_items"></div>
        <div class="rss" id="chan_pubDate"></div>
        <div class="rss" id="chan_copyright"></div>
    </div>

As you can see, the root div element has a number of child div tags. These tags will be populated with the data in the RSS object by the showRSS(RSS) function, which is shown below.

function showRSS(RSS)
{
    /*A*/
    var imageTag = "<img id='chan_image'";
    var startItemTag = "<div id='item'>";
    var startTitle = "<div id='item_title'>";
    var startLink = "<div id='item_link'>";
    var startDescription = "<div id='item_description'>";
    var endTag = "</div>";

    /*B*/
    var properties = new Array("title","link","description","pubDate","copyright");
    for (var i=0; i<properties.length; i++)
    {
        eval("document.getElementById('chan_"+properties[i]+"').innerHTML = ''"); /*B1*/
        curProp = eval("RSS."+properties[i]);
        if (curProp != null)
            eval("document.getElementById('chan_"+properties[i]+"').innerHTML = curProp"); /*B2*/
    }

    /*C*/
    /*show the image*/
    document.getElementById("chan_image_link").innerHTML = "";
    if (RSS.image.src != null)
    {
        document.getElementById("chan_image_link").href = RSS.image.link; /*C1*/
        document.getElementById("chan_image_link").innerHTML = imageTag
            +" alt='"+RSS.image.description
            +"' width='"+RSS.image.width
            +"' height='"+RSS.image.height
            +"' src='"+RSS.image.url
            +"' "+"/>"; /*C2*/
    }


    /*D*/
    document.getElementById("chan_items").innerHTML = "";
    for (var i=0; i<RSS.items.length; i++)
    {
        item_html = startItemTag;
        item_html += (RSS.items[i].title == null) ? "" : startTitle + RSS.items[i].title + endTag;
        item_html += (RSS.items[i].link == null) ? "" : startLink + RSS.items[i].link + endTag;
        item_html += (RSS.items[i].description == null) ? "" : startDescription + RSS.items[i].description + endTag;
        item_html += endTag;
        document.getElementById("chan_items").innerHTML += item_html; /*D1*/
    }

    return true;
}

A: As we have no way of knowing the number of channel items in the RSS feed, we must dynamically generate the HTML for the RSS items. These are the default values for the HTML tags that will contain the RSS2Item data. For compatibility, we also dynamically generate the img HTML tag.

B: We traverse the string properties in the RSS2Category object here, similar to how we did in the constructor. In order to clear any data that may remain from an old RSS feed, we reset the innerHTML property on line B1. We are able to fetch the specific div element that we need from the HTML by calling getElementById(). Providing that the property is defined, we set the div element to its new value on line B2.

C: Again, we use the getElementById() function to get the HTML element that will contain the image from the RSS feed. As the image should be linkable, we use an anchor element (a) instead of a div element. The href attribute in the anchor element specifies what the image should link to, so we assign it to the value found in RSS.image.link (C1). The content of the element is filled in using the innerHTML property, as we have done in part B (C2).

D: Here is where we display the items in the RSS object. A div tag is defined for each RSS item, containing the title, link, and description. For the sake of clarity, the other properties have been omitted. Each div tag is appended to the contents of the chan_items parent tag using the innerHTML property (D1).

Wrap-Up

The Ajax RSS parser has been tested in IE 6.0 and Firefox 1.5.0.6 for Windows XP. The RSS2Channel object does not support all of the elements in the RSS 2.0 specification. The ones that have been omitted are cloud, textInput, skipHours, and skipDays. For the most part, these RSS elements are only useful on the server side, so it wouldn't make sense to include them in a client-side parser.

After noting the length of the code, you may be thinking that the same functionality could have been accomplished with half the number of lines of code. In particular, we could have completely omitted the RSS object by writing the showRSS(RSS) function in a way that reads the RSS properties directly from the XML element. Certainly, this is possible. However, showRSS() is only meant to be an example of how the RSS2Channel object can be used. By defining an RSS object that contains meaningful RSS data, we have a much more scalable application. For example, the code can be easily extended to fetch multiple feeds. The RSS objects from these feeds can then be manipulated, or compared with other feeds (you can fetch a new feed after a certain interval, and compare it with the old one). The point of a separate RSS object is to make increasingly complex applications like this easier to develop.

All of the files that were discussed are available below:
The HTML file: rssajax.html
The JavaScript file, containing the RSS parser: rssajax.js
Sample RSS file 1: test-rss.xml
Sample RSS file 2: google-rss.xml


Comment on this articleShare your experience in our forums.
(* You must be a
member of XML.com to use this feature.)
Comment on this Article


Titles Only Titles Only Newest First
  • Parsing live feeds
    2009-04-21 11:25:36 YoonMi [Reply]

    Can you utilize this script calling an external RSS feed source such as CNN, Yahoo, Google, etc...?


    Thanks,
    YoonMi

  • local files works but remote not.
    2009-04-05 05:36:24 Olijf [Reply]

    What is the problem??
    I am an javascript newbie but i like to use it on my site.
    Is it also possible to open an default rss instead of the option menu??

  • Cant get it to work on Firefox 2
    2008-07-08 18:38:44 ray888 [Reply]

    It works fine in IE but not Firefox 2. When I load an RSS I just get a blank screen. Any updates on the codes so that it works in Firefox 2?


    Thanks,


    ray

  • Items with different amount of properties?
    2008-03-08 09:01:58 johangoras [Reply]

    Hi i'm kind of new to the rss and really need some help. Your example works perfect, but my modifications of it are not! The items in my RSS feed looks like this:
    <item>
    <title>Product</title>
    <link>http://...</link>
    <description>...</description>
    <group>TV</group>
    <property1>color</property1>
    <property2>weight</property2>
    <property3>size</property3>
    </item>


    My problem is that all products can have a different amount of properties, how do I fetch them???


    I've managed to create an array with all properties and stuff but I can't get it to work with the tmpElement:


    function array_merge(arr)
    {
    var merged = arr;
    for (var i = 1; i < arguments.length; i++)
    {
    merged = merged.concat(arguments[i]);
    }

    return merged;
    }


    function RSS2Item(itemxml)
    {
    //Get properties
    var property_array = new Array();
    var k = 0;
    var elements =itemxml.getElementsByTagName("*");


    for(var i = 0; i < elements.length; i++)
    {
    if(elements[i].tagName.substring(0, 8) =="property")
    {
    property_array[k] = elements[i].tagName;
    k++;
    }
    }


    /*B*/
    var properties = array_merge(new Array("title", "link", "description", "group"), property_array);


    var tmpElement = null;
    for (var i=0; i {
    tmpElement = itemxml.getElementsByTagName(properties[i])[0];


    if (tmpElement != null)
    {
    //HERE IS THE PROBLEM, NODEVALUE IS EMPTY!
    eval("this."+properties[i]+" = tmpElement.childNodes[0].nodeValue");
    }
    }
    }

  • Can not fetch from remote server
    2007-12-17 05:16:46 or_gust [Reply]

    hi i'm new to this technology. and need some help.
    as you mentioned earlier, this reader will work with remote rss. i tried replacing "test-rss.xml" with "http://www.mysite.org/feed.xml" in html but it return no feed results and also no errors at all. i ran the code in local Tomcat server and also in my remote webhost. i got the same result. i'm i missing something?

  • the XML pages are not shown when clicked
    2007-08-02 09:27:28 cumap [Reply]

    Am I missing something here cause I kept clicking but no XML page has shown at all. Should I copy the XML pages into the same folder of the file is located cause if so, I'd already done so, and still, no luck here!!!


    My knowledge in JS is very limited so please be understanding. :-)

    • the XML pages are not shown when clicked
      2007-08-02 09:47:23 cumap [Reply]

      Nevermind my question cause after messing around, I realized the js file I saved is rssajax.js and the link name in the script was rssajax6.js. How stupid can I be? :-)

  • WIll this work with direct URL submission...
    2007-06-15 13:18:17 Amanjeev [Reply]

    Just wanted to know that if the rss feed is not locally stored and say I want to fetch Cnet.com news feed automatically, will this work if I just give the feed address.


    AJ

    • WIll this work with direct URL submission...
      2007-06-27 06:54:11 agb81 [Reply]

      I'm interested in the same thing. I want to use this for a wordpress blog where the feed address is http://user.wordpress.com/feed/. Is it possible to do this without storing the xml file on the server?

      • WIll this work with direct URL submission...
        2007-06-27 07:21:22 sobes [Reply]

        Yes, I believe it will work. However, you may get a warning on your browser, depending on your security settings.


        I recommend fetching the remote RSS file on your local server. This is pretty easy to do using php: http://ca.php.net/manual/en/ref.curl.php (example 417).

        • WIll this work with direct URL submission...
          2008-03-15 02:23:59 Arvindpatel [Reply]

          This application is working in IE perfectly but in mozilla nothing it is displaying for remote rss files.Is it possible to make workable in mozilla also for remote rss files.

  • outside link, not local
    2007-05-30 08:34:28 FJBrian [Reply]

    I'm missing something in the code.
    Trying to post a common RSS feed yet when parsing it, it adds my URL to the beginning like this:


    actual feed:
    somesite.com/something.xml


    mysite.com/somesite.com/something.xml

    • outside link, not local
      2007-06-15 13:23:41 Amanjeev [Reply]

      Can't I run this HTML without putting in a webserver? I tried to run it but it gives me Error 0 received:


      I do not understand this.

      • outside link, not local
        2007-06-27 07:23:44 sobes [Reply]

        Yes, this needs to run in a web server in order for it to work. See the "JavaScript - Error Code 0 Received" thread below.

        • outside link, not local
          2009-10-21 07:16:04 Levitikon [Reply]

          I have been using this script with success for a while now, but just recently we changed to a new proxy server and now I get the error 0. For clarity, the url of the feed contains the HTTP:// as mentioned above. One last point; when I refresh the page it loads the feed. Any ideas?

  • Refresh Problems
    2007-03-05 15:44:21 martha123 [Reply]

    Great codes! I have one issue, whenever I refresh, the content disappears. Any ideas?

    • Refresh Problems
      2007-03-16 21:23:18 sobes [Reply]

      You need to store the state of your AJAX application on the client-side (browser). I recently blogged about how you can do it here: http://dev.aol.com/blog/846.


      Unfortunately, I didn't get a chance to provide a concrete code-based answer, but it should give you some ideas. Hope it helps!


      Paul Sobocinski
      (author)

  • JavaScript - Error Code 0 Received
    2007-01-31 06:53:56 UIGuy [Reply]


    A question for those more knowledgeable than myself...


    I run the demo on the site and it works.


    I drop the four code files into Apache's htdocs folder and when I select the 'fetch rss feed' button, I get an Error Code 0 Received...


    Thoughts? I am certain this is simple, but I can't figure it out...


    Thanks...


    UIGuy


    BTW - System consists of Tiger Apache2 (MAMP) setup...




    • JavaScript - Error Code 0 Received
      2007-01-31 08:58:07 UIGuy [Reply]


      OK - On a whim I put the code on a machine running an UBUNTU LAMP setup and it worked fine.


      My original problem (with my mac setup) remains. If anyone has any ideas as to what I apparently need to change in the config, please let me know...


      Thanks - UIGuy

    • JavaScript - Error Code 0 Received
      2007-01-31 06:55:14 UIGuy [Reply]


      I forgot to mention that I am using Firefox as my browser...

      • JavaScript - Error Code 0 Received
        2007-01-31 10:04:10 sobes [Reply]

        I get the same exact error message if I try to open the file (i.e. not the URL) using my browser (both with MSIE and Firefox).


        Make sure you are accessing the page through HTTP; the address bar should say something like http://localhost/rssreader/rssajax.html. If it doesn't start with "http://" you're simply viewing the HTML file in your browser, so client-server communication is not possible.


        Paul S.

  • This code doesn`t work in Opera
    2006-10-14 12:10:13 Rudnytskiy [Reply]

    This code doesn`t work in Opera 9.0.


    And I don`t know ways to solve this problem.


    Can you help me?


    Thanks in advance.

  • eval() unnecessary
    2006-09-17 05:29:48 happygiraffe [Reply]

    Just a minor point. The call to eval() in order to do dynamic object properties is not really necessary. This is because


    object.property = "foo";


    is exactly the same as


    object["property"] = "foo";


    Thanks for the interesting read, however!


    -Dom

  • Excellent work,but..
    2006-09-14 07:13:13 Eki [Reply]

    Really nice work, innovative, client side function is a truly welcomed feature. Yet, the links in the feed do not eiher exist or work. The URL's of the items are there, but not as links; cannot understand why, because the essential service is now simply not there. Any help?

    • Excellent work,but..
      2006-09-15 07:00:38 sobes [Reply]


      Thanks for your feedback. Admittedly, a better way to do it would have been to place the links inside anchor (<a>) elements instead of <div> elements. This would make the links active. However it's easy to modify the code to do so. Here are the steps to make the channel link active:


      1) Change the <div id="chan_link"></div> to <a id="chan_link" href=""></a> in the HTML file

      2) Add the following line to the JavaScript code:

      document.getElementById("chan_link").href = RSS.link;

      Add this line just below the for loop that populated the channel elements (labelled /*B*/ in the code).


      To do the same to the item links, use a similar approach:


      1) Modify the HTML declared in the JavaScript code at the start of the showRSS(RSS) function. Specifically, substitute the "var startLink ..." line with the following two lines:


      var startLink = "<a id='item_link' href='";

      var endLink = "</a>";


      2) Replace the "item_html += (RSS.items[i].link..." line with the following:


      item_html += (RSS.items[i].link == null) ? "" : startLink + RSS.items[i].link + "'>"+ RSS.items[i].link + endLink;


      The links themselves may not work, as I have used old sample RSS feeds that may be outdated. In conjunction with this reader, you will need to implement a server-side script that actually rebuilds the RSS files on a regular basis, thus keeping the content fresh and avoiding outdated links.


      I hope you found that helpful!

      Paul Sobocinski. (author)



  • Poor JavaScript quality
    2006-09-14 02:36:03 Asbjørn Ulsberg [Reply]

    The JavaScript quality wasn't the best I've seen. Not the HTML either, but since that isn't really the topic, I'll resist the urge to comment upon it any further. But the JavaScript doesn't do much error recovery, doesn't declare all variables, doesn't check object existance prior to their usage and does some really ugly and nasty HTML concatenation with innerHTML.


    Plus, everything is just loose functions without any protection from other JavaScripts one might want to use on the same page. Instead, all of the functions should be kept inside a wrapper function or object to avoid conflicts with other scripts.


    I would advice the author to, instead of trying to invent his own set of wheels in this area, use existing libraries for basic stuff like this. Both Yahoo's Ajax library and Prototype are excellent and hides all this mess from the author and on top of that does all of this much neater and better than most others (including me. And the author of this article).

    • Poor JavaScript quality
      2006-09-15 07:31:43 sobes [Reply]


      First off, thanks very much for your feedback on my article. This is the first time I've written for XML.com, so all responses are much appreciated.


      The JavaScript quality wasn't the best I've seen. Not the HTML either, but since that isn't really the topic, I'll resist the urge to comment upon it any further. But the JavaScript doesn't do much error recovery, doesn't declare all variables, doesn't check object existance prior to their usage and does some really ugly and nasty HTML concatenation with innerHTML.


      I tried to keep the JavaScript as simple and short as possible, while conveying the main point of the article - how to translate an RSS feed received through AJAX into a series of simple JavaScript objects. Although I didn't declare all the variables, I deliberately listed all object properties (variables) at the top of the object constructors so that custom declarations for them can be added easily by someone who'd wish to extend the code. Object detection is used when necessary (eg: "if (catElement == null)..." in the RSS2Category constructor).


      I acknowledge that using DOM functions to create the HTML elements would be a more scalable way of displaying the RSS on the webpage. I used innerHTML for two reasons: (1) cross-browser compatibility and (2) simplicity. As mentioned, showRSS(RSS) is not meant to be the focus of the article. Using DOM functions would mean having a much larger showRSS(RSS) function, and there'd be a few browser workarounds that I would've had to explain.


      Plus, everything is just loose functions without any protection from other JavaScripts one might want to use on the same page. Instead, all of the
      functions should be kept inside a wrapper function or object to avoid conflicts with other scripts.


      This is a good suggestion and an example of how the code could be extended to work within a larger JavaScript application. The code for the project is included as a separate ".js" library file precisely to make this relatively simple to do.


      I would advice the author to, instead of trying to invent his own set of wheels in this area, use existing libraries for basic stuff like this. Both Yahoo's Ajax library and Prototype are excellent and hides all this mess from the author and on top of that does all of this much neater and better than most others (including me. And the author of this article).


      Before even planning out this article, I had done research on AJAX libraries, as well as other examples of RSS parsers or readers that have been implemented through AJAX. Despite my research, I was unable to find anything that clearly and comprehensively explains the process of implementing an RSS reader with AJAX in a simple way. Although both of the sources you suggest are excellent examples of AJAX libraries, neither of them actually implement a reader for RSS 2.0. As the AJAX that is used in the article is quite simple (it's pretty much encased in the getRSS() function), I chose not to use an AJAX library.


      Again, thank you for your feedback, and I hope that you've found my response helpful.

      Paul Sobocinski. (author)



    • Poor JavaScript quality
      2006-09-14 23:01:33 allanc@chickenandporn.com [Reply]

      I think the author's intention was to show a bit of AJAX and show how the XML nature of the AJAX allows the existing tools (browser, javascript) to do much of the work for us.


      The additional error-checking and protection you discuss might have obfuscated the code, perhaps it would have made a nice appendix or next-page to show the reader what kind of protections are needed.


      Leveraging existing tools incurs dependency -- for example, anyone who has said that perl is the easiest hasn't worked through a DLL-Hell to try to get back the 2-yr-old environment that made a stack of perl work. For this same reason, re-inventing a while is more work to the benefit of having no dependencies. I agree that this is a case where the dependencies add value.


      Maybe that is an example that you're very suited to add to this forum. Engineers talk in terms of words, patches, and code. Care to show some code? It might help to show your point, and further assist readers of the original article.


      If my words sound argumentative, it's not intended; I want to applaud the author for putting forth this work for others' benefit and to the scrutiny of the more experienced readers. Very generous!


      Allan Clark
      I make linux handsets; my AJAX sucks

  • Developing the code
    2006-09-13 23:57:15 StuartTurner [Reply]

    You could extend the article to show how an XSL Transformation might simplify the code which processe the RSS content - I believe both IE and Firefox support transformations (if not you could use one of the public XSLT services which are available)