Friday, May 7, 2010

How to bind Non-standard RSS Feed to DataGrid in Silverlight

I stuck at this problem for around 1 week..and finally,I had found out the solution.I see there are not much documentations about this hence I would like to share this solution with you all.

One of the disadvantages of Silverlight is it does not support the use of dataset...which we usually use it for data binding...So how are we going to bind xml to datagrid in Silverlight without using dataset?

Well,in this post,I'm gonna to focus on how to use the SyndicationFeed.ElementExtensions Class to extract the content of the non-standard RSS Feed. Usually, RSS Feed are the standard XML file with some standard parser for example : link,title,pubDate,summary and so on. However,what if your RSS Feed is a geo location feed? How are we going to set the parser to read the desire node without having to scan through the xml structure?

In this example,I'm going to use LINQ to select the node's content.LINQ is easy to be used. I like to use LINQ because we do not need to crack our head on how to creating a for-loop reading from nodes to nodes.

Here are the steps to bind your RSS Feed to DataGrid in Silverlight.

1. Download the RSS Feed to the Internet Temporarily Folder.

serviceUrl = new Uri(TextBox1.Text.Trim());
WebClient wc = new WebClient(); wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(serviceUrl);
2. In this function "wc_OpenReadCompleted" ,I include this:

using (XmlReader reader = XmlReader.Create(s))
{
feed = SyndicationFeed.Load(reader);
foreach (SyndicationItem feedItem in feed.Items)
{
feedItems.Add(feedItem);
}
var posts = from item in feedItems
select new RSSFeed()
{
title = item.Title.Text,
NavURL = item.Links[0].Uri.AbsoluteUri,
Description = item.Summary.Text,
geoPoint =item.ElementExtensions.ReadElementExtensions("point", yourNodeElementNamespace).FirstOrDefault()


};

DataGrid1.ItemsSource = posts;
DataGrid1.Visibility = Visibility.Visible;

In this part,you can see that, for the 1st argument in this method,is the node Element node name and the 2nd argument is the namespace of your desire node.

I take this as the example of my XML resource.

3. Right click the browser to view source.You can see at the 1s line, the xmlns:geo and xmlns:dc.
What if you wish to crawl the data of tag "geo:lat" ?

Ok,well,is pretty easy,you can add the namespace of the "geo" in the xmlns which is http://www.w3.org/2003/01/geo/wgs84_pos#

into this syntax "item.ElementExtensions.ReadElementExtensions("lat", yourNodeElementNamespace).FirstOrDefault();"

Note that the 1st argument of this method takes the name of the node,in this case, we want to crawl the tag"geo:lat" content. Hence we include "lat" as the 1st argument. The latter,we include the "geo" namespace,which is http://www.w3.org/2003/01/geo/wgs84_pos#


Well,it is not easy to read/consume a very dynamic yet non-standard xml file or RSS Feed in Silverlight. I haven't explored if there is any better solution in Silverlight 4.0 yet.

I hope this sharing would solve your problem.

Thanks for viewing this blog.

2 comments:

  1. Wwow! first of all I thank u for this topic!
    It's my first time to think about RSS Feed... now I see it's important and easy(as you said).

    thank you for having encouraged me to deal in and use it

    ReplyDelete
  2. opps...found ur blog accidently...LinQ is indeed much easier than the traditional method...however, my superior does not allows me to use it cuz he believes in a lecturer's words (which is, LinQ is sux and slow)...so i have to stick on the data reader way...

    ReplyDelete