2

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?

6
  • Your first problem was failing to post an example of the failing XML. I don't know what your second problem is, because of your first problem. Commented Aug 3, 2009 at 22:17
  • Maybe your second problem is you didn't set a breakpoint in the foreach loop? Did you try that, or did you depend on the debugger? Commented Aug 3, 2009 at 22:19
  • I would hazard a guess that the answer is "xml namespaces". Do you have example xml? Commented Aug 3, 2009 at 22:22
  • I updated the post with the value of the response string (see here: snipt.org/lWm) And I did set the breakpoints, and stepped through it. It totally skips the loop, the count of entries is 0. Commented Aug 3, 2009 at 22:24
  • Sample XML is here: snipt.org/lWm Commented Aug 3, 2009 at 22:24

3 Answers 3

7

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)

Sign up to request clarification or add additional context in comments.

5 Comments

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.
Since the namespace is inherited, <id> is in the same namespace. You need to qualify anything that isn't in the default namespace.
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?
media is an alias to a different namespace; use var media = XNamespace.Get("search.yahoo.com/mrss/");, then entry.Elements(media + "group").
What is the difference between using XNamespace.Get("namespace.com/") and just declaring a string of type XNamespace, like XNamespace ns = "namespace.com"?
3

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"

Comments

2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.