Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Parse podcast RSS feed in C#

Posted on 2009-06-27
6
Medium Priority
?
1,771 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 21

Accepted Solution

by:
MogalManic earned 2000 total points
ID: 24735277
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
ID: 24735572
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
ID: 24735577
... also, you list an interface called IRssHandler.  Is there code for that please?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 21

Expert Comment

by:MogalManic
ID: 24735908
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
ID: 24736307
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
ID: 31597638
Thanks!  Excellent advice.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

650 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