Working with RSS Feeds on WP8 Development

 

Really Simple Syndication or RSS is a method of receiving constantly updated links to your chosen websites. Once you have set up a connection to a website you will receive a list of all the stories currently shown on a certain page or section of that site.

RSS feeds benefit publishers by letting them syndicate content automatically. A standardized XML file format allows the information to be published once and viewed by many different programs. They benefit readers who want to subscribe to timely updates from favorite websites or to aggregate feeds from many sites into one place.

How to use data from RSS feeds in WP8 development?

RSS Feeds: (https://www.7daysindubai.com/news.rss)

<?xml version="1.0" encoding="UTF-8"?>

<rss xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:media="https://search.yahoo.com/mrss/" version="2.0"> <channel>

<title>Dubai News RSS feed</title>

<link>https://www.7daysindubai.com/news.rss</link>

<description>Dubai News RSS feed</description>

<language>en-gb</language>

<item>

<title>Survey reveals UAE children are eating too much junk food</title>

<link>https://www.7daysindubai.com/Survey-reveals-UAE-children-eating-junk-food/story-18956855-detail/story.html</link>

<description>A research team, led by Dr Habiba I Ali of Al Ain University, found that Emirati teenagers and young children are munching their way through fast food and saturated fats and are lacking in calcium and Vitamins A, D and E. Boys aged nine to 18 were bad at eating their greens &amp;ndash; every boy surveyed in that age group is not eating enough vegetables. The team of researchers, which also included the National Nutrition Institute in Cairo and two US universities, found that only a third of nine...&lt;p&gt;&lt;img src="https://www.7daysindubai.com/images/localworld/ugc-images/276156/Article/images/18956855/4840489-thumb.jpg" alt="Survey reveals UAE children are eating too much junk food" title="Survey reveals UAE children are eating too much junk food"/&gt;&lt;/p&gt;</description>

<pubDate>Sat, 11 May 2013 23:15:00 GMT</pubDate>

<guid isPermaLink="false">https://www.7daysindubai.com/Survey-reveals-UAE-children-eating-junk-food/story-18956855-detail/story.html</guid>

<media:description>Survey reveals UAE children are eating too much junk food</media:description> <media:thumbnail url="https://www.7daysindubai.com/images/localworld/ugc-images/276156/Article/images/18956855/4840489-thumb.jpg" width="90" height="60" />

<media:content type="image/jpg" url="https://www.7daysindubai.com/images/localworld/ugc-images/276156/Article/images/18956855/4840489-thumb.jpg" />

<dc:creator>7DAYS</dc:creator>

</item>

<item>

<title>PHOTOS: Super 7 meets Catboy and Geordiebird at Dubai 92 studios</title> <link>https://www.7daysindubai.com/pictures/PHOTOS-Super-7-meets-Catboy-Geordiebird-Dubai-92/pictures-18963291-detail/pictures.html</link>

<description>Gallery created by 7DAYS&lt;p&gt;&lt;img src="https://www.7daysindubai.com/images/localworld/ugc-images/276156/Gallery/images/18963291/4840858-thumb.jpg" alt="PHOTOS: Super 7 meets Catboy and Geordiebird at Dubai 92 studios" title="PHOTOS: Super 7 meets Catboy and Geordiebird at Dubai 92 studios"/&gt;&lt;/p&gt;</description>

<pubDate>Sun, 12 May 2013 08:08:20 GMT</pubDate>

<guid isPermaLink="false">https://www.7daysindubai.com/pictures/PHOTOS-Super-7-meets-Catboy-Geordiebird-Dubai-92/pictures-18963291-detail/pictures.html</guid>

<media:description>PHOTOS: Super 7 meets Catboy and Geordiebird at Dubai 92 studios</media:description> <media:thumbnail url="https://www.7daysindubai.com/images/localworld/ugc-images/276156/Gallery/images/18963291/4840858-thumb.jpg" width="90" height="60" />

<media:content type="image/jpg" url="https://www.7daysindubai.com/images/localworld/ugc-images/276156/Gallery/images/18963291/4840858-thumb.jpg" />

<dc:creator>7DAYS</dc:creator> 

</item>

</channel>

</rss>

 

1. Define a class to store each News story

public class NewsItem
{
    public string title { get; set; }
    public Uri link { get; set; }
    public string description { get; set; }
    public string pubDate { get; set; }
    public string imageTitle { get; set; }
    public string imageThumbnail { get; set; }
    public string creator { get; set; }
}

2. Define a class to store a Newsgroup which will contain a group of NewsItems

public class NewsGroup : BindableBase
  {
      public string title { get; set; }
      public Uri link { get; set; }
      public string description { get; set; }
      public string language { get; set; }
      public string icon { get; set; }
      private List<NewsItem> news = new List<NewsItem>();
      public List<NewsItem> News
      {
          get
          {
              return news;
          }
          set
          {
              SetProperty(ref news, value);
          }

      }
  }

3. BindableBase is a class that needs to be defined as follows for a dynamic databinding of the model and viewmodel

public abstract class BindableBase : INotifyPropertyChanged
   {
       public event PropertyChangedEventHandler PropertyChanged;
       protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
       {
           if (object.Equals(storage, value)) return false;

           storage = value;
           this.OnPropertyChanged(propertyName);
           return true;
       }
       protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
       {
           var eventHandler = this.PropertyChanged;
           if (eventHandler != null)
           {
               eventHandler(this, new PropertyChangedEventArgs(propertyName));
           }
       }
   }

4. Add nuget – HTTP Client Libraries - https://nuget.org/packages/Microsoft.Net.Http

To add nuget

- Right click on References

- Manage Nuget Packages

- With the online option chosen on the left panel, search for the nuget

- Install

5. Define a class called DataSource with the following content

// to convert element got from xml tree to string

public static class DataSource

   {

       private static string GetVal(XElement element, object key)

       {

           try

           {

               return element.Element(key.ToString()).Value;

           }

           catch

           {

               return "";

           }

       }

// to get the first attribute of an xml element

private static string GetVal2(XElement element, object key)
      {
          try
          {
              return element.Element(key.ToString()).FirstAttribute.Value;
          }
          catch
          {
              return "";
          }
      }

  public static async Task<NewsGroup> GetNewsGroup(string uri)

    {

        HttpClient httpClient = new HttpClient();

        var xmlFeed = await httpClient.GetStringAsync(new Uri(uri));

        XDocument loadedData = XDocument.Parse(xmlFeed);

        var element = loadedData.Root; // element has been set to the root of the xml tree which is rss

        XNamespace media = "https://search.yahoo.com/mrss/"; // as you can see, highlighted in red above, media is a separate namespace and we define this in our code so that we can access its elements.

        XNamespace dc = "https://purl.org/dc/elements/1.1/";

        List<NewsItem> NewsList = new List<NewsItem>();

        foreach (var var in loadedData.Root.Descendants("item"))//  this loop runs for each item that is a child of the root element named “item”. Here it is each news item.

            try

            {

                NewsList.Add(new NewsItem

            {

                title = GetVal(var,"title"),

                link = new Uri(GetVal(var,"link"), UriKind.Absolute),

                pubDate = GetVal(var,"pubDate"),

                imageTitle = GetVal(var,media + "description"), // this has been done as media is a separate namespace and description has been defined in that namespace

                imageThumbnail = (GetVal2(var, media + "thumbnail"));// as can be seen in the RSS Feed file that the image url is the first attribute of the element “media:thumbnail”

                creator = GetVal(var,dc + "creator"),

                description = GetVal(var, "description")

            });

            }

            catch {

            }

        var ele = element.Element("channel");

        return new NewsGroup

        {

            title =ele.Element("title").Value,

            description = ele.Element("description").Value,

            link = new Uri(ele.Element("link").Value, UriKind.Absolute),

            language = ele.Element("language").Value,

            News = NewsList

        };

    }

}

This method is asynchronous with a return type of NewsGroup. Once it has completed you will have your NewsGroup with the list of News Feeds in the list – News.

6. Now call this method in your ViewModel

public class MainPageViewModel : BindableBase
   {
       private NewsGroup news;
       public NewsGroup News
       {
           get
           {
               return news;
           }
           set
           {
               SetProperty(ref news, value);
           }

       }

public async Task LoadData()
     {

        News = await DataSource.GetNewsGroup("https://www.7daysindubai.com/news.rss");

}

7. Now call LoadData from the MainPage.xaml.cs

protected async override void OnNavigatedTo(NavigationEventArgs e)
   {
       var vm = this.LayoutRoot.DataContext as MainPageViewModel;
           await vm.LoadData();

}

And now you have your rss feeds!

PS: Please add the required namespaces by pressing ctrl+’.’ on the words that are not recognized by visual studio without their namespace.