Solved

Parse podcast RSS feed in C#

Posted on 2009-06-27
6
1,651 Views
Last Modified: 2013-11-18
I am having some difficulty with podcast RSS feeds.  I am able to read the feed in and parse the tags without a problem, but I run into problems as I iterate through each item in the channel and trying to figure out which attribute actually has the link to the MP3.  

Some feeds use the link tag, others use the enclosure and then there are the itunes tags.  Is there any advice on the best way to handle this?

This is the code I'm currently working with.
if (string.IsNullOrEmpty(url))

                throw new ArgumentNullException("url");
 

           RSSFeed feed = new RSSFeed();
 

            try

            {

                string content = GetURLSource(url);

                XmlDocument rssDoc = new XmlDocument();

                rssDoc.LoadXml(content);

                XmlNodeList rssNodes = rssDoc.SelectNodes("/rss/channel/item");
 

                feed.Link = rssDoc.SelectSingleNode("/rss/channel/link") != null ? rssDoc.SelectSingleNode("/rss/channel/link").InnerText : string.Empty;

                feed.Title = rssDoc.SelectSingleNode("/rss/channel/title") != null ? rssDoc.SelectSingleNode("/rss/channel/title").InnerText : string.Empty;

                feed.Description = rssDoc.SelectSingleNode("/rss/channel/description") != null ? rssDoc.SelectSingleNode("/rss/channel/description").InnerText : string.Empty;
 

                if (rssNodes != null)

                    foreach (XmlNode node in rssNodes)

                    {

                        RSSEvent rssEvent = new RSSEvent

                        {

                            CopyRight = node.SelectSingleNode("copyright") != null ? node.SelectSingleNode("copyright").InnerText : string.Empty,

                            Description = node.SelectSingleNode("description") != null ? node.SelectSingleNode("description").InnerText : string.Empty,

                            Link = node.SelectSingleNode("link") != null ? node.SelectSingleNode("link").InnerText : string.Empty,

                            PubDate = node.SelectSingleNode("pubdate") != null ? node.SelectSingleNode("pubdate").InnerText : string.Empty,

                            Title = node.SelectSingleNode("title") != null ? node.SelectSingleNode("title").InnerText : string.Empty,

                            EnclosureUrl = node.SelectSingleNode("enclosure") != null ? node.SelectSingleNode("enclosure").Attributes["url"].InnerText : string.Empty,

                            EnclosureType = node.SelectSingleNode("enclosure") != null ? node.SelectSingleNode("enclosure").Attributes["type"].InnerText : string.Empty,

                            EnclosureLength = node.SelectSingleNode("enclosure") != null ? node.SelectSingleNode("enclosure").Attributes["length"].InnerText : string.Empty

                        };
 

                        feed.Events.Add(rssEvent);

                    }

            }

            catch (Exception ex)

            {

                throw new Exception(ex.Message, ex.InnerException);

            }
 

            return feed;

Open in new window

0
Comment
Question by:andy_ee
  • 3
  • 3
6 Comments
 
LVL 21

Accepted Solution

by:
MogalManic earned 500 total points
Comment Utility
Instead of doing an if for every node, I would try to determine the type and then delegate the parsing to the specific handler.  That way you will have only one logical expression and the code would be much easier to read.

Something like this:

 

  IRssHandler handler=null;

  if (rssDoc.SelectNodes(...)=="???")

    handler=new ITunesRSSHandler(rssDoc);

  else if (rssDoc.SelectNodes(...2)==""???2"

    handler - new PodCast1Handler(rssDoc)

  //......One if for each handler type
 

 feed=handler.parseFeed();

feed.Events.addRange(handler.ParseEvents());
 
 

//And one handler would look like this

public class PodCastHandler : IRSSHandler

{

    PodCastHandler(XmldDocument rssDoc)

    {

       //Initialze class...

       XmlNodeList rssNodes = rssDoc.SelectNodes("/rss/channel/item");

       //...

    }
 

    public Feed parseFeed()

    {

         RSSFeed feed = new RSSFeed();

 

         feed.Link = rssDoc.SelectSingleNode("/rss/channel/link").InnerText;

         feed.Title = rssDoc.SelectSingleNode("/rss/channel/title").InnerText;

         feed.Description = rssDoc.SelectSingleNode("/rss/channel/description").InnerText;

 

         return feed;
 

    }

 

    public RSSEvent[] parseEvents()

    {

       RssEvent[] events=null;

       if (rssNodes != null)

       {

          events=new RssEvents[rssNodes.Count];

          foreach (XmlNode node in rssNodes)

          {

               RSSEvent rssEvent = new RSSEvent

               CopyRight = node.SelectSingleNode("copyright").InnerText;

               //...Set Other properties...

               events[evtIdx++]=rssEvent;

          }

       }

       return events;

     }

}

Open in new window

0
 

Author Comment

by:andy_ee
Comment Utility
Excellent response.  However I need to find a clean way of differentiating between a podcast feed and an iTunes feed.
0
 

Author Comment

by:andy_ee
Comment Utility
... also, you list an interface called IRssHandler.  Is there code for that please?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 21

Expert Comment

by:MogalManic
Comment Utility
IRssHandler is the base interface for all of the "RSS Handlers".  It would look something like this:
public interface IRssHandler

{

    ///<Summary>Parse the root element of the feed and build a Feed object</Summary>

    public Feed parseFeed();

    ///<Summary>Parse the feed events into RSSEvent collection</Summary>

    public RSSEvent[] parseEvents();

}

Open in new window

0
 
LVL 21

Expert Comment

by:MogalManic
Comment Utility
To check if it is a iTunes feed you should just check to see if it has an itunes namespace.  Something like this:
if (rssDoc.DocumentElement.GetAttribute("xmlns:itunes")!="")

  handler=new iTunesRSSHandler(rssDoc);

else if //Other rss types here

Open in new window

0
 

Author Closing Comment

by:andy_ee
Comment Utility
Thanks!  Excellent advice.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
Browsers only know CSS so your awesome SASS code needs to be translated into normal CSS. Here I'll try to explain what you should aim for in order to take full advantage of SASS.
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. 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.: (CODE)

744 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now