Использование LINQ to XML для обработки XML в нескольких пространствах имен - PullRequest
2 голосов
/ 04 августа 2009

Я пытаюсь проанализировать результаты из API YouTube. Я получаю результаты правильно в виде строки, но не могу разобрать его правильно.

Я следовал предложениям в предыдущей теме, но не получил никаких результатов.

Мой пример кода:

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
}

Проблема в том, что записи имеют счетчик 0, хотя XDocument явно имеет допустимые значения.

Значение переменной ответа (образец XML) можно увидеть здесь: http://snipt.org/lWm

(К вашему сведению: схема youTube приведена здесь: http://code.google.com/apis/youtube/2.0/developers_guide_protocol_understanding_video_feeds.html)

Может кто-нибудь сказать мне, что я здесь делаю не так?

Ответы [ 3 ]

7 голосов
/ 04 августа 2009

Все данные находятся в пространстве имен "http://www.w3.org/2005/Atom"; вы должны использовать это для:

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)
    ...
};

и т. Д. (Не проверено)

3 голосов
/ 04 августа 2009

Когда вы видите prefix:name, это означает, что name находится в пространстве имен, префикс которого был объявлен как prefix. Если вы посмотрите на верхнюю часть документа, вы увидите xmlns:media=something. something - это пространство имен, используемое для всего с префиксом media.

Это означает, что вам нужно создать XNamespace для каждого из пространств имен, на которые вы хотите сослаться:

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

и затем используйте media для имен в этом пространстве имен:

media + "group"

Пространства имен в этом документе:

 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"
2 голосов
/ 04 августа 2009

Вам необходимо установить пространство имен.

Создание XName в пространстве имен
Как и в случае с XML, XName может находиться в пространстве имен или в пространстве имен.
Для C # рекомендуемый подход для создания XName в пространстве имен состоит в том, чтобы объявить объект XNamespace, а затем использовать переопределение оператора сложения.

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

...