views:

1045

answers:

3

I'm trying to parse results from the YouTube API. I'm getting the results correctly as a string, but am unable to parse it correctly.

I followed suggestions on a previous thread, but am not getting any results.

My sample code is:

string response = youtubeService.GetSearchResults(search.Term, "published", 1, 50);
XDocument xDoc = XDocument.Parse(response, LoadOptions.SetLineInfo);
var list = xDoc.Descendants("entry").ToList();
var entries = from entry in xDoc.Descendants("entry")
              select new
              {
                  Id = entry.Element("id").Value,
                  Categories = entry.Elements("category").Select(c => c.Value)
                  //Published = entry.Element("published").Value,
                  //Title = entry.Element("title").Value,
                  //AuthorName = entry.Element("author").Element("name").Value,
                  //Thumnail = entry.Element("media:group").Elements("media:thumnail").ToList().ElementAt(0)
              };
foreach (var entry in entries)
{
    // entry.Id and entry.Categories available here
}

The problem is that entries has a count of 0 even though the XDocument clearly has the valid values.

The value of the response variable (Sample XML) can be seen here: http://snipt.org/lWm

(FYI: The youTube schema is listed here: http://code.google.com/apis/youtube/2.0/developers_guide_protocol_understanding_video_feeds.html)

Can anyone tell me what I'm doing wrong here?

+5  A: 

All the data is in the "http://www.w3.org/2005/Atom" namespace; you need to use this throughout:

XNamespace ns = XNamespace.Get("http://www.w3.org/2005/Atom");

...

from entry in xDoc.Descendants(ns + "entry")
select new
{
    Id = entry.Element(ns + "id").Value,
    Categories = entry.Elements(ns + "category").Select(c => c.Value)
    ...
};

etc (untested)

Marc Gravell
That fixed it. Thanks!Just so I understand, why do I need to add the namespace before the name of each element. Since the element is simply <id> not <namespace id> or something... I would assume that if a namespace was needed, I would add it once to the XDocument only.
rksprst
Since the namespace is inherited, `<id>` is in the same namespace. You need to qualify anything that isn't in the default namespace.
Marc Gravell
One of the elements I need is named: <media:group> ... when I use entry.Element(ns + "media:group") I get an error. Is there a specific way to access this element?
rksprst
media is an alias to a different namespace; use `var media = XNamespace.Get("search.yahoo.com/mrss/");`, then `entry.Elements(media + "group")`.
Marc Gravell
What is the difference between using XNamespace.Get("http://namespace.com/") and just declaring a string of type XNamespace, like XNamespace ns = "http://namespace.com/"?
@blparker - nothing ;-p
Marc Gravell
+2  A: 

You need to set the namespace.

Creating an XName in a Namespace
As with XML, an XName can be in a namespace, or it can be in no namespace.
For C#, the recommended approach for creating an XName in a namespace is to declare the XNamespace object, then use the override of the addition operator.

http://msdn.microsoft.com/en-us/library/system.xml.linq.xname.aspx

280Z28
+2  A: 

When you see prefix:name, it means that name is in the namespace whose prefix has been declared as prefix. If you look at the top of the document, you'll see an xmlns:media=something. The something is the namespace used for anything with the prefix media.

This means you need to create an XNamespace for each of the namespaces you need to reference:

XNamespace media = XNamespace.Get("http://search.yahoo.com/mrss/");

and then use media for the names in that namespace:

media + "group"

The namespaces in this document are:

 xmlns="http://www.w3.org/2005/Atom" 
 xmlns:app="http://www.w3.org/2007/app" 
 xmlns:media="http://search.yahoo.com/mrss/" 
 xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" 
 xmlns:gd="http://schemas.google.com/g/2005" 
 xmlns:gml="http://www.opengis.net/gml" 
 xmlns:yt="http://gdata.youtube.com/schemas/2007" 
 xmlns:georss="http://www.georss.org/georss"
John Saunders