Hello all,

I'm attaching a 'beta' RSS parsing search which will currently parse
valid RSS .9, .91, .92, 1.0, 2.0 and many other RDF feeds. If anyone
can provide me with links to other RSS version feeds, I'll be happy to
TRY to make it capable of working with all of them. :)

[Usage]:
  rssx url-of-rss-feed

[Variables]:
//the number of milliseconds between 'popping' the next
//rss feed result in the popup box. This will set the
//popup timeout to 5 seconds:
  rssxTimeOutAfter = 5000;

[Examples]:
  rssx http://ReliableAnswers.com/rss.asp
  rssx http://ReliableAnswers.com/jobs/news-rss.asp
  rssx http://slashdot.org/slashdot.rdf
  rssx http://royo.is-a-geek.com/SiteFeeder/GetFeed.aspx?FeedId=30
  rssx http://regexlib.com/Rss.aspx
  rssx http://royo.is-a-geek.com/SiteFeeder/GetFeed.aspx?FeedId=42
  rssx http://www.lockergnome.com/lockergnome.xml
  rssx http://royo.is-a-geek.com/SiteFeeder/GetFeed.aspx?FeedId=27
  rssx http://news.netcraft.com/index.rdf
  rssx http://www.benmeadowcroft.com/rss/weblog.rdf
  rssx http://www.eff.org/rss/press.xml
  rssx
http://www.vbaccelerator.com/home/The_Site/Indexes/RSS_Feeds/WhatsNew/
rss.xml
  rssx http://www.mvps.org/emorcillo/news.xml

[Advanced]:
  One of the nifty things about this search is that you can
'daisy-chain' this search one after another in the box or in code and
it'll append the popups to the end of the queue. If you want to have
it display a dozen RSS feeds from different sources every hour you can
put this code in your localprefs (untested, but it stands to logic):

function myfeeds(){
  rssx http://ReliableAnswers.com/rss.asp
  rssx http://ReliableAnswers.com/jobs/news-rss.asp
  rssx http://slashdot.org/slashdot.rdf
  rssx http://royo.is-a-geek.com/SiteFeeder/GetFeed.aspx?FeedId=30
  rssx http://regexlib.com/Rss.aspx
  rssx http://royo.is-a-geek.com/SiteFeeder/GetFeed.aspx?FeedId=42
  rssx http://www.lockergnome.com/lockergnome.xml
  rssx http://royo.is-a-geek.com/SiteFeeder/GetFeed.aspx?FeedId=27
  rssx http://news.netcraft.com/index.rdf
  rssx http://www.benmeadowcroft.com/rss/weblog.rdf
  rssx http://www.eff.org/rss/press.xml
  rssx
http://www.vbaccelerator.com/home/The_Site/Indexes/RSS_Feeds/WhatsNew/
rss.xml
  rssx http://www.mvps.org/emorcillo/news.xml
  setTimeout("myfeeds()",3600000);
}
myfeeds();


[Problem / Why it's Beta]:
  Here's the crux. I've got it working for all but one of the RSS
feeds I had in my RSS collection (which is dozens of feeds from
various sources).

BEWARE attempting to test it using this feed, since it WILL crash
DQSD, and probably Windows while it's at it. The crash occurs
immediately upon calling send() from the xmlhttp object. I don't know
why. In fact, I have ABSOLUTELY NO idea (which is strange for me). It
just stalls, freezing up everything. I'm using asynchronous calls and
spiffy function loading, array chaining, every optimization I can
think of to make this code sweet, portable, dynamic and effective,
while using the smallest footprint (and yes, 11 kb of code WAS really
necessary to make this thing parse that wide a variety of RSS feeds).

Are you ready for a laugh? The only feed that it COULD NOT parse is
the syndication feed FROM THE W3C:
  rssx http://www.w3.org/2000/08/w3c-synd/home.rss
For some reason their server doesn't respond to the xmlhttp object,
but it will to PERL GET, IE, Mozilla, Netscape and other shtuff. I've
played with the headers but just can't get it to work. :(

Oh, and I do not *think* it is the stylesheet that they've embedded,
since it should *still* return something to the client (and make it as
far as the 'finished loading' onreadystatechange=4), but it doesn't.
It just freezes immediately upon send(). The Ben Meadowcroft site (
http://www.benmeadowcroft.com/rss/weblog.rdf ), for example, uses a
stylesheet as well, but my code processes and returns correctly.

Any advice/thoughts are very much appreciated!

Regards,

Shawn K. Hall
http://ReliableAnswers.com/

'// ========================================================
   "I have discovered that all human evil comes from this,
    man's being unable to sit still in a room."
      -- Blaise Pascal (1623 - 1662)
<search function="rssx">
  <name>RSS Feed Parser</name>
  <description>Parses an RSS feed and pops the results every 8 seconds (configurable).
    <div class="helpboxDescLabels">Switches:</div>
    <table class="helpboxDescTable">
      <tr><td>url</td><td> - </td><td> URL of RSS Feed to process. </td></tr>
    </table>
    <div class="helpboxDescLabels">Examples:</div>
    <table class="helpboxDescTable">
      <tr><td>rssx http://ReliableAnswers.com/rss.asp</td></tr>
    </table>
  </description>
  <category>Functions</category>
  <link>http://ReliableAnswers.com/x/dqsd/</link>
  <contributor>Shawn K. Hall</contributor>
  <script><![CDATA[
      function rssx(q){
	if( q == "?" ){
	  qsfind("rssx /function");
	  return false;
	}
	var sUrl = ((isURL(q)) ? q : "http://reliableanswers.com/rss.asp";);

	try{
	//attempt to obtain the remote RSS feed
	  var xmlHttp = new ActiveXObject("Microsoft.XmlHttp");
	  xmlHttp.onreadystatechange = function() { 
		 if (xmlHttp.readyState==4) {
		  rssxXmlParser( xmlHttp, sUrl );
		 }
		};
	  xmlHttp.open("GET", sUrl, true);
	  xmlHttp.setRequestHeader ( "Accept", "application/xml, text/xml, text/rss, application/xml+rdf, */*" );
	  xmlHttp.setRequestHeader ( "User-Agent", "Mozilla/4.0 (compatible; DQSD ( http://www.dqsd.net/ ); rssx Search ( http://ReliableAnswers.com/x/dqsd/ ))" );
	  xmlHttp.send(null);
	}catch(e){
	  alert("RSSX: Failure!\n" + e.number + "::" + e.description);
	}
      }

function rssxXmlParser( xmlHttp, sUrl ){
 var sBuild = "";
 try{
//get the response content from the remote site
  var sBody = xmlHttp.responseText;
  sBody = sBody.replace(/(\<\?xml-stylesheet[^>]*>)/gim,"<!-- $1 -->");
  var xBody = new ActiveXObject("MSXML2.DOMDocument");
  xBody.loadXML( sBody );
  if(xBody.parseError.errorCode != 0)
    throw new Error(0, "RSS is not well-formed.\nParse error: " + xBody.parseError.reason + " line: " + xBody.parseError.line.toString() + ", col: " + xBody.parseError.linepos.toString() + "\n" + xBody.parseError.srcText);

//parse it
  var xElement = xBody.documentElement;

//rss version, capabilities and format
//default paths and properties
  var rDate    = "pubdate";
  var rLanguage= "";
  var rItems   = "item";
  var rImage   = "image";
  var rInput   = "textinput";
  var rVersion = "";
  var rSyPeriod= "";
  var rSyFreq  = "";
  var rContent = "";
  var rsTitle  = "";
  var rsImage  = "";
  var rsLink   = "";

//document element name
  var rDocElem = xElement.nodeName;

//version="1.0"
  xNode = xElement.attributes.getNamedItem("version");
  if (xNode != null) rVersion = xNode.nodeTypedValue;
  switch (rVersion){
	case "":	rItems = "item"; rImage = "image"; rInput = "textinput"; break;
	case "0.9":
	case "0.91":
	case "0.92":
	case "1.0":
	case "2.0":
	default:
		rItems = "channel/item"; rImage = "channel/image"; rInput = "channel/textinput"; break;
  }

//xmlns="http://purl.org/rss/1.0/";
  xNode = xElement.attributes.getNamedItem("xmlns");
  var rXmlns = ((xNode != null) ? xNode.nodeTypedValue : "");

//xmlns:dc="http://purl.org/dc/elements/1.1/";
  xNode = xElement.attributes.getNamedItem("xmlns:dc");
  var rXmlnsDc = ((xNode != null) ? xNode.nodeTypedValue : "");
  if (rXmlnsDc != "") {
    rDate = "dc:date";
    xNode = xElement.selectSingleNode("channel");
    if (xNode != null) {
      xNodeSub = xNode.selectSingleNode("dc:language");
      if (xNodeSub != null) rLanguage = xNodeSub.nodeTypedValue;
    }
  }

//xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
  xNode = xElement.attributes.getNamedItem("xmlns:rdf");
  var rXmlnsRdf= ((xNode != null) ? xNode.nodeTypedValue : "");

//xmlns:sy="http://purl.org/rss/1.0/modules/syndication/";
  xNode = xElement.attributes.getNamedItem("xmlns:sy");
  var rXmlnsSy = ((xNode != null) ? xNode.nodeTypedValue : "");
  if (rXmlnsSy != "") {
    xNode = xElement.selectSingleNode("channel");
    if (xNode != null) {
      xNodeSub = xNode.selectSingleNode("sy:UpdatePeriod");
      if (xNodeSub != null) rSyPeriod = xNodeSub.nodeTypedValue;
      xNodeSub = xNode.selectSingleNode("sy:UpdateFrequency");
      if (xNodeSub != null) rSyFreq   = xNodeSub.nodeTypedValue;
    }
  }

//xmlns:content="http://purl.org/rss/1.0/modules/content/";
  xNode = xElement.attributes.getNamedItem("xmlns:content");
  var rXmlnsContent = ((xNode != null) ? xNode.nodeTypedValue : "");
  if (rXmlnsContent != "") rContent = "content:encoded";

//obtain image/title/link properties
  xNode = xElement.selectSingleNode( rImage );
  if (xNode != null) {
    xNodeSub = xNode.selectSingleNode("title");
    if (xNodeSub != null) rsTitle= xNodeSub.nodeTypedValue;
    xNodeSub = xNode.selectSingleNode("url");
    if (xNodeSub != null) rsImage= xNodeSub.nodeTypedValue;
    xNodeSub = xNode.selectSingleNode("link");
    if (xNodeSub != null) rsLink = xNodeSub.nodeTypedValue;
  }

//enumerate RSS items
  var xNodes = xElement.selectNodes( rItems );
  for (i=0; i < xNodes.length; i++){
  //get variables for this resource
    var xNode = xNodes.item(i);
    xNodeSub  = xNode.selectSingleNode("title");
    var sTitle= ((xNodeSub != null) ? xNodeSub.nodeTypedValue : "");
    xNodeSub  = xNode.selectSingleNode("description");
    var sDesc = ((xNodeSub != null) ? xNodeSub.nodeTypedValue : "");
    sDesc = sDesc.replace(/<a[\s]*[^>]href="([^"]+)"[^>]*>/gim,"<a onClick=\"window.parent.openSearchWindow('$1')\">");
    xNodeSub  = xNode.selectSingleNode("link");
    var sLink = ((xNodeSub != null) ? xNodeSub.nodeTypedValue : "");
    if (sLink == ""){
      xNodeSub  = xNode.selectSingleNode("guid");
      var sLink = ((xNodeSub != null) ? xNodeSub.nodeTypedValue : "");
    }
    if (rContent != ""){
      xNodeSub  = xNode.selectSingleNode( rContent );
      var sContent = ((xNodeSub != null) ? xNodeSub.nodeTypedValue : "");
      sContent = sContent.replace(/<a[\s]*[^>]href="([^"]+)"[^>]*>/gim,"<a onClick=\"window.parent.openSearchWindow('$1')\">");
    }else{
      var sContent = "";
    }

  //append this record
    sBuild = "";
    sBuild+= "<table width=\"100%\" border=\"0\" onClick=\"window.parent.openSearchWindow('" + sLink + "')\"><tr>";
    if (rsLink != ""){
      sBuild+= "<td width=\"5%\">";
      sBuild+= "<a href=\"" + rsLink + "\" title=\"" + rsTitle + "\">";
      if (rsImage != ""){
        sBuild+= "<img src=\"" + rsImage + "\" border=\"0\" />";
      }else{
	sBuild+= rsTitle;
      }
      sBuild+= "</a></td>";
    }else{
      sBuild+= "<td width=\"5%\">";
      sBuild+= "<a href=\"http://reliableanswers.com/x/dqsd/?rss="; + sUrl + "\">";
      if (rsImage != ""){
        sBuild+= "<img src=\"" + rsImage + "\" border=\"0\" />";
      }else{
        sBuild+= "[RSSX]";
      }
      sBuild+= "</a></td>";
    }
    sBuild+= "<td>";
    sBuild+= "<p align=\"left\"><b>" + sTitle + "</b></p>";
    sBuild+= "</td></tr>\n";
    sBuild+= "<tr><td colspan=\"2\">";
    sBuild+= "<p>" + sDesc + "</p>";
    if (sContent != ""){
      sBuild+= "<hr />" + sContent;
    }
    sBuild+= "</td></tr>\n";
    sBuild+= "</table>\n\n";
    rssxSearchArray[rssxSearchArray.length] = sBuild;
  }
  if (rssxSearchArray.length > 0){
    if (rssxDisplayAgain == false) displayRssxSearchPopup();
  }
 }catch(e){
  alert("RSSX: Failure!\n" + e.number + "::" + e.description);
 }
}


var rssxSearchPopup;
var rssxSearchIndex = 0;
var rssxSearchArray = Array();
var rssxDisplayAgain= false;
var rssxSearchURL   = '';
if (typeof rssxTimeOutAfter == "undefined") rssxTimeOutAfter = 6000;


function displayRssxSearchPopup(){
  if (typeof rssxTimeOutAfter == "undefined") rssxTimeOutAfter = 8000;
  var windowW = 380;
  rssxSearchPopup = window.createPopup();
  var rssxContent = rssxSearchArray[0];
  rssxSearchArray = rssxSearchArray.slice(1);
  var rssxSearchPopupBody = rssxSearchPopup.document.body;
  var rssxSearchPopupBodyCode = "<html><head></head><body>";
  rssxSearchPopupBodyCode += "<table id=rstable border=0 cellspacing=1 cellpadding=2 width=100% height=100%>";
  rssxSearchPopupBodyCode += "<tr><td valign=top><style>" + convertStylesToInline() + "</style>";
  rssxSearchPopupBodyCode += "<tr><td valign=top style='text-align: center' class=helpboxDescriptions>" + rssxContent;
  rssxSearchPopupBodyCode += "</tr></td></table></body></html>";
  rssxSearchPopupBody.innerHTML = rssxSearchPopupBodyCode;
  rssxSearchPopup.document.body.style.border="outset 2px";
  rssxSearchPopup.document.body.style.background='menu';
  rssxSearchPopup.document.body.style.overflowY='auto';

// Temporarily show the popup to determine the proper final height for the popup.
  rssxSearchPopup.show(0, 0, windowW, 0);
  var windowH = rssxSearchPopupBody.scrollHeight + 6;
  rssxSearchPopup.hide();

// Put a cap on the popup height
  windowH = windowH > window.screen.height-100 ? window.screen.height-100 : windowH;

// Display it
  rssxSearchPopup.show((buttonalign == "left" ? 0 : document.body.clientWidth - windowW), -windowH, windowW, windowH, document.body);

// Set next display + timeout
  if (rssxSearchArray.length > 0){
    rssxDisplayAgain = true;
    setTimeout("rssxSearchPopup.hide();rssxSearchPopup='';displayRssxSearchPopup();",rssxTimeOutAfter);
  }else{
    rssxDisplayAgain = false;
    setTimeout("rssxSearchPopup.hide();rssxSearchPopup='';",rssxTimeOutAfter);
  }
}
  ]]></script>
  <copyright>
  Copyright (c) 2004 Shawn K. Hall
  Distributed under the terms of the GNU Public License, Version 2 (http://www.gnu.org/copyleft/gpl.txt)
  </copyright>
</search>

Reply via email to