Solved

jquery to parse rss feed document

Posted on 2009-07-14
15
1,540 Views
Last Modified: 2012-05-07
Hello there,

I am trying to parse a rss feed with jquery, the structure is like below. I have no problem find the tag value with <title> or <description> but have problem to select  tag like <blip:runtime> I think because of the : in the tag. I tried to change the code to find blip\\:runtime and it works for FF, but not in IE. Please help. Thanks

<channel>
<title>epicvideo : propertyCat - blip.tv (beta)</title>
<link>http://blip.tv</link>
<description>kyyvideo : propertyCat - blip.tv (beta)</description>
<language>en-us</language>
<generator>http://blip.tv</generator>
<lastBuildDate>Mon, 16 Feb 2009 05:40:30 +0000</lastBuildDate>
<pubDate>Mon, 16 Feb 2009 05:40:30 +0000</pubDate>
<item>
<guid isPermaLink="false">8927984A-FBDC-11DD-8798-B136E023344A</guid>
<link>http://blip.tv/file/1778242</link>
<title>a single house</title>
<blip:user>kyy</blip:user>
<blip:userid>3267</blip:userid>
<blip:safeusername>kyy</blip:safeusername>
<blip:show>kyy</blip:show>
<blip:showpage>http://video.blip.tv/</blip:showpage>
<blip:picture>http://blip.tv/skin/blipnew/placeholder_user.gif</blip:picture>
.
.
<blip:adChannel/>
<blip:recommendations>0</blip:recommendations>
<blip:recommendable>0</blip:recommendable>
<blip:adminRating/>
<blip:runtime>21</blip:runtime>
<blip:embedLookup>Ae2MPJP+Kw</blip:embedLookup>
<blip:embedUrl type="application/x-shockwave-flash">http://blip.tv/play/Ae2MPJP+Kw</blip:embedUrl>
<wfw:commentRss>http://blip.tv/comments/?attached_to=post1787352&skin=rss</wfw:commentRss>
<blip:thumbnail_src>Epicvideo-343-564.jpg</blip:thumbnail_src>

<blip:smallThumbnail>http://a.images.blip.tv/Epicvideo-343-564-412.jpg</blip:smallThumbnail>
<blip:license>No license (All rights reserved)</blip:license>
<description>
Description goes here
</description>

$.get('videoquest.aspx?rss='+list,function(xml){	
	
	xp=xml;	
	desc=new Array();
	var thm=new Array();
	var video=new Array();
	var title=new Array();
	var pure = new Array();	
	var runtime = new Array();
	var item = new Array();
	$(xp).find('blip\\:smallThumbnail').each(function(){
             var id_text = $(this).text();
             alert (id_text);        	           // shows nothing ...
			thm.push (id_text);
         }); //close each  	
    $(xp).find('enclosure').each(function(){
             var id_text = $(this).attr('url');
             alert (id_text);                          // shows all the video name
			video.push (id_text);                         
         }); //close each 
....

Open in new window

0
Comment
Question by:tomcattyy
  • 8
  • 7
15 Comments
 
LVL 82

Expert Comment

by:hielo
ID: 24853477
var data={};
$(xp).find("item > *").each(function(){
 var nodeName=$(this).get(0).nodeName;
 //see if nodeName starts with blip
 if( /^blip/.test(nodeName) )
 {
   //change the colon to an underscore
   data[ nodeName ] = $(this).text();
 }
});

alert(data["blip:user"]);
alert(data["blip:userid"]);

//or you can iterate:
for( var k in data)
{
 alert( k + "=" + data[k]);
}
0
 
LVL 1

Author Comment

by:tomcattyy
ID: 24853919
Thanks Hielo,

I put in the code, but it seems this snippet did not save results to the array data. Is .test a jquery standard function? I do the  alert( k + "=" + data[k]); and nothing to show. appreciate your help

if( /^blip/.test(nodeName) )
 {
   //change the colon to an underscore
   data[ nodeName ] = $(this).text();
 }
0
 
LVL 82

Expert Comment

by:hielo
ID: 24854114
>>I put in the code, but it seems this snippet did not save results to the array data.
(Technically, it is an object, not an array)  Where did you declare var data={}? Try putting it OUTSIDE of the .get() -ex:

var data={};
$.get('videoquest.aspx?rss='+list,function(xml){ ...} );

>>Is .test a jquery standard function?
No! It is a method of the javascript RegExp object.
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 82

Expert Comment

by:hielo
ID: 24854222
BTW: using $.get() is convenient because it is very simple, however, if you have errors in your xml, your function will not get called. If you use the .ajax functions, you can supply an error callback function and if that gets called, you immediately will know there  is something wrong with your xml.  On the xml you are working on, your xml is required to have a namespace declaration for "blip". If it is not there, then your function will not be called. If you continue to have problems, please provide a test url to your project.

Regards
0
 
LVL 1

Author Comment

by:tomcattyy
ID: 24854848
Hello Hielo,

I change the data{} out of the $.get and get data{} saved with the data in FF, in IE just simply blank. no error either. the xml feed is coming from blip.tv, so I think the format is correct. I check the source and the namespace is defined correct as you described. FF has no problem to parse the file and display all the data I need. Do you think I need to use .ajax?
Please take a look at this url
http://208.75.252.245/videocategory.htm?json=179900
with FF you will see the display of data{} and the final table. with IE just a blank table.
the proxy page is in
http://208.75.252.245/videoquest.aspx?json=179900
I tried to change the tag name in proxy aspx to make it no colon: , FF still works and IE can see the tag but cannot read the this.text() out. so I will have a table with the pic blank and only the info without blip.

Appreciate your help
0
 
LVL 1

Author Comment

by:tomcattyy
ID: 24855289
Hello Hielo,

here is the url that removed the colon from the tag, IE cannot  read the $(this).text(), can you find a way for IE to be able to read the text()? Thanks
http://208.75.252.245/videocategory2.htm?id=179900
0
 
LVL 82

Expert Comment

by:hielo
ID: 24860153
I redefined $.getList() for debugging purposes, and it seems ie detects a parseError when xml is specified as the dataType. I need to put this on hold now, but will look at it later.
var returnedDataType="xml"
	$.getList=function(list){
		$.ajax({
   				type: "GET",
				url: "http://208.75.252.245/videoquest.aspx",
				data: "json="+list,
				dataType:returnedDataType,
				error:function(XMLHttpRequest, textStatus, errorThrown){
					alert(textStatus+"\n"+XMLHttpRequest.responseText)
				},
				success: function(data, textStatus){
					var r=data.documentElement.getElementsByTagName("item");
					alert(r.length)
				}
		});//end:$.ajax()
	}

Open in new window

0
 
LVL 82

Expert Comment

by:hielo
ID: 24861453
I don't know why it is reporting a parseError. Try changing utf-8 to iso-8859-1 to see if that helps. Additionally, try sending
Content-type: text/xml

Even if that manages to get rid of the parseError, it still does not understand "item > *".  I think you will need to end up handling IE differently. See attached code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
<html>
<head>
<title>Untitled</title>
</head>
<body>
 
<script  type="text/javascript">
 
function start()
{
	var objXML = new ActiveXObject("MSXML.DOMDocument");
	objXML.async = false;
	objXML.load("http://208.75.252.245/videoquest.aspx?json=179899");
	objXML.setProperty("SelectionNamespaces", 'xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:blip="http://blip.tv/dtd/blip/1.0" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:amp="http://www.adobe.com/amp/1.0" xmlns:dcterms="http://purl.org/dc/terms" xmlns:gm="http://www.google.com/schemas/gm/1.1" xmlns:mediaad="http://blip.tv/dtd/mediaad/1.0"');
	var items = objXML.documentElement.selectNodes("/rss/channel/item");
	var i=-1,limit=items.length;
	var data=[];
	while(++i<limit)
	{
		data[data.length] = {"user":items[i].selectSingleNode("blip:user").text
								,"userid":items[i].selectSingleNode("blip:userid").text
								,"posts_id":items[i].selectSingleNode("blip:posts_id").text
								,"picture":items[i].selectSingleNode("blip:picture").text
								};
	}
	//now let's see what you got
	var i=-1,limit=data.length;
	while(++i<limit){
		alert(data[i].posts_id);
	}
}
 
window.onload=start;
 
</script>
 
</body>
</html>

Open in new window

0
 
LVL 1

Author Comment

by:tomcattyy
ID: 24861838
Thanks.
0
 
LVL 82

Expert Comment

by:hielo
ID: 24862194
you are welcome
0
 
LVL 1

Author Comment

by:tomcattyy
ID: 24863549
Thanks Hielo,

your code is perfect in IE now. I tried to put the below code to make it work on both ie and FF, but obviously my understanding is not enough. If not too complicated can you make it work ? the error message I have is    objXML.documentElement.selectNodes is not a function

try //Internet Explorer
  {
  var objXML = new ActiveXObject("MSXML.DOMDocument");
  objXML.async="false";
   objXML.load("http://208.75.252.245/videoquest.aspx?json=179899");
   objXML.setProperty("SelectionNamespaces", 'xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:blip="http://blip.tv/dtd/blip/1.0" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:amp="http://www.adobe.com/amp/1.0" xmlns:dcterms="http://purl.org/dc/terms" xmlns:gm="http://www.google.com/schemas/gm/1.1" xmlns:mediaad="http://blip.tv/dtd/mediaad/1.0"');
  }
catch(e)
  {
  parser=new DOMParser();
  objXML=parser.parseFromString("http://208.75.252.245/videoquest.aspx?json=179899","text/xml");
  }

var items = objXML.documentElement.selectNodes("/rss/channel/item");
...
0
 
LVL 82

Expert Comment

by:hielo
ID: 24864816
you already now how to make it work with FF. So I was expecting you to so something like:


function start(url)
{
        var objXML = new ActiveXObject("MSXML.DOMDocument");
        objXML.async = false;
        objXML.load(url);
        objXML.setProperty("SelectionNamespaces", 'xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:blip="http://blip.tv/dtd/blip/1.0" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:amp="http://www.adobe.com/amp/1.0" xmlns:dcterms="http://purl.org/dc/terms" xmlns:gm="http://www.google.com/schemas/gm/1.1" xmlns:mediaad="http://blip.tv/dtd/mediaad/1.0"');
        var items = objXML.documentElement.selectNodes("/rss/channel/item");
        var i=-1,limit=items.length;
        var data=[];
        while(++i<limit)
        {
                data[data.length] = {"user":items[i].selectSingleNode("blip:user").text
                                                                ,"userid":items[i].selectSingleNode("blip:userid").text
                                                                ,"posts_id":items[i].selectSingleNode("blip:posts_id").text
                                                                ,"picture":items[i].selectSingleNode("blip:picture").text
                                                                };
        }
 
        //now let's see what you got
/*
        var i=-1,limit=data.length;
        while(++i<limit){
                alert(data[i].posts_id);
        }
*/
return data;
}
 
 
 
 $.getList=function(list){
  var data=null;
  var url="http://208.75.252.245/videoquest.aspx?json="+list;
  if( "undefined" !== typeof(ActiveXObject) )
  {
   /*IMPORTANT: the IE function will return an array that contains objects. There will be one array index per item. So if you rss has 3 item nodes, and you want to know the "blip:user" for the first item then you will need to alert( data[0]["blip:user"] ) */
    data = hanldeIE();
  }
  else
  {
   //here you should use what you already had working for firefox.
  }
}
 
$.getList(23121);

Open in new window

0
 
LVL 82

Accepted Solution

by:
hielo earned 500 total points
ID: 24864833

<html>
 
<head><base href="http://208.75.252.245/videocategory.htm?json=179900"/>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>New Page 1</title>
<script type="text/javascript" src="scripts/jquery-1.2.6.min.js"></script>
 
<script type="text/javascript">
		
$(function()
{
	$.play=function (x)
	{
		$('#show').html('').append(desc[x]);
	}
	var desc=new Array();
	var Ax = new Array();
	var data=[];
	$.getList = function(list)
	{
	 	var url='videoquest.aspx?json='+list;
		if("undefined"!==typeof(ActiveXObject) )
		{
			data=IE_Fetch(url);
		}
		else
		{
			$.get(url,function(xml)
			{	
				var xp ="";
				xp=xml;
				$(xp).find("item > *").each(function(i)
				{
					var nodeNamez=$(this).get(0).nodeName;
					/*
					//if you want specific nodes, then use the commented switch below instead
					//and adjust the list with the nodes you are interested in. Modify the IE function as well	
					switch( nodeNamez )
					{
						case "blip:user":
						case "blip:userid":
						case "blip:posts_id":
						case "blip:picture":
							data[i][ nodeNamez ] = $(this).text();
							break;
					}
					*/
 
					//as it currently is, ALL the nodes are returned (including those that do NOT
					//start with blip). If you want only those that begin with blip, then uncomment
					//the following if statement. Modify the IE function as well	
					//if( /^blip/i.test(nodeNamez) )
					{
						data[i][ nodeNamez ] = $(this).text();
					}
				});// end each item
			});//end: $.get()
		}//end:else
 
alert("total <item> nodes: "+data.length);
//let's look at the contents of first node
var str="";
for( var n in data[0])
{
	str += n + "\t"+data[0][n]+"\n";
}
alert("First Item has:\n\n" +str);
/*
	//you can iterate over the items extracted.
		while(data.length){
			var temp=data.shift();
			for( var p in temp)
			{
				alert(temp[p])
			}
		}
*/
 
 
	/*
		//you probably don't need these any more since everything is in data array.
		desc=new Array();
		var thm=new Array();
		var video=new Array();
		var title=new Array();
		var pure = new Array();	
		var runtime = new Array();
		var item = new Array();
	
		$(xp).find("blip\\:smallThumbnail").each(function(){
			var id_text = $(this).text();
			//alert (id_text);        	
			thm.push (id_text);
		}); //close each  	
 
		$(xp).find('enclosure').each(function(){
			var id_text = $(this).attr('url');
             //alert (id_text);  
			video.push (id_text);                         
		}); //close each
	    
		$(xp).find('title').each(function(){
			var id_text = $(this).text()             
			title.push (id_text);            
		}); // each   
 
		$(xp).find('description').each(function(){
             var id_text = $(this).text()             
			desc.push (id_text);            
		}); // each       
 
		$(xp).find('blip\\:puredescription').each(function(){
             var id_text = $(this).text()    
             //alert (id_text);        	
			pure.push (id_text);
		}); //close each  	
 
		$(xp).find('blip\\:runtime').each(function(){
             var id_text = $(this).text()            	
			runtime.push (id_text);
		}); //close each  	
 
		$(xp).find('blip\\:item_id').each(function(){
             var id_text = $(this).text()            	
			item.push (id_text);
         }); //close each  	
 
		var nav="<table border='1' cellspacing='0'>";        	
		for (i=0; i<thm.length ; i++){
			var m=i+1;
			nav+="<tr><td><img src="+thm[i]+"></td><td>"+title[m]+"<br />"+pure[i]+"<br />"+(parseFloat(runtime[i])/60).toFixed(2)+"min<br />";
			nav+="<button onClick=newEntry("+item[i]+")>&#21152;&#20837;&#25773;&#25918;&#24433;&#38598;</button>&nbsp;<button>&#31435;&#21051;&#25773;&#25918;</button></td></tr>"
		}
		nav+="</table>";
		alert (nav);
		$('#xm').append(nav); 
	*/
 
	}; // end of getList
 
	//var selection=location.href .split("=");
	//var selitem=selection[1];
	$.getList('179899');
});
 
 
 
function IE_Fetch(url)
{
	var objXML = new ActiveXObject("MSXML.DOMDocument");
	objXML.async = false;
	objXML.load(url);
	objXML.setProperty("SelectionNamespaces", 'xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:blip="http://blip.tv/dtd/blip/1.0" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:amp="http://www.adobe.com/amp/1.0" xmlns:dcterms="http://purl.org/dc/terms" xmlns:gm="http://www.google.com/schemas/gm/1.1" xmlns:mediaad="http://blip.tv/dtd/mediaad/1.0"');
	var items = objXML.documentElement.selectNodes("/rss/channel/item");
	var i=-1,limit=items.length;
	var data=[];
	while(++i<limit)
	{
		var temp={};
		var children=items[i].selectNodes("*");
		var j=-1,cLimit=children.length;
		while(++j<cLimit)
		{
			/*
			//if you want specific nodes, then use the commented switch below instead
			//and adjust the list with the nodes you are interested in.
			switch(children[j].nodeName)
			{
				case "blip:user":
				case "blip:userid":
				case "blip:posts_id":
				case "blip:picture":
					temp[children[j].nodeName]=children[j].text
					break;
			}
			*/
 
			//as it currently is, ALL the nodes are returned (including those that do NOT
			//start with blip). If you want only those that begin with blip, then uncomment
			//the following if statement
			//if ( /^blip/i.test(children[j].nodeName) )
			{
				temp[children[j].nodeName]=children[j].text
			}
		}
		data[i]=temp;
	}
return data;
}
</script>
 
 
</head>
 
<body>
 
<button onclick ="init()">Button</button>
<div id="xm">I am here </div>
<div id="show"></div>
</body>
 
</html>

Open in new window

0
 
LVL 1

Author Comment

by:tomcattyy
ID: 24864892
Thanks again Hielo, you are the number 1.
0
 
LVL 1

Author Closing Comment

by:tomcattyy
ID: 31603437
complete and thoughtful solutions, so lucky to have experts like this to help.
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction A frequently asked question goes something like this:  "I am running a long process in the background and I want to alert my client when the process finishes.  How can I send a message to the browser?"  Unfortunately, the short answer …
How to build a simple, quick and effective accordion menu using just 15 lines of jQuery and 2 css classes
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question