У меня возникли проблемы с извлечением нужного элемента в приложении C# для Windows Phone 8, которое извлекает потоки данных YouTube. XML-документ показан ниже. Это из плейлиста YouTube:
<entry gd:etag="W/"YDwqeyM."" xmlns:gd="https://schemas.google.com/g/2005" xmlns="https://www.w3.org/2005/Atom">
<media:group xmlns:media="https://search.yahoo.com/mrss/">
<media:category label="Science & Technology" scheme="https://gdata.youtube.com/schemas/2007/categories.cat">Tech</media:category>
<media:content url="https://www.youtube.com/v/vt7PLhQKYlU?version=3&f=playlists&app=youtube_gdata" type="application/x-shockwave-flash" medium="video" isDefault="true" expression="full" duration="1668" yt:format="5" xmlns:yt="https://gdata.youtube.com/schemas/2007" />
<media:content url="rtsp://r5---sn-p5qlsu7d.c.youtube.com/CiULENy73wIaHAlVYgoULs_evhMYDSANFEgGUglwbGF5bGlzdHMM/0/0/0/video.3gp" type="video/3gpp" medium="video" expression="full" duration="1668" yt:format="1" xmlns:yt="https://gdata.youtube.com/schemas/2007" />
<media:content url="rtsp://r5---sn-p5qlsu7d.c.youtube.com/CiULENy73wIaHAlVYgoULs_evhMYESARFEgGUglwbGF5bGlzdHMM/0/0/0/video.3gp" type="video/3gpp" medium="video" expression="full" duration="1668" yt:format="6" xmlns:yt="https://gdata.youtube.com/schemas/2007" />
<media:credit role="uploader" scheme="urn:youtube" yt:display="TheDigitalDigest" yt:type="partner" xmlns:yt="https://gdata.youtube.com/schemas/2007">thedigitaldigest</media:credit>
<media:description type="plain">Surface 2</media:description>
<yt:videoid xmlns:yt="https://gdata.youtube.com/schemas/2007">vt7PLhQKYlU</yt:videoid>
</media:group>
</entry>
Мне нужно изменить приведенный ниже код, который анализирует запись с помощью методов XNamespace/XElement для поиска элемента yt:video вместо элемента id . Я могу без проблем добраться до элементов, которые не имеют префикса пространства имен (те, которые не содержат двоеточие). Вот код, который мне нужно изменить:
public YouTubeVideo(XNamespace atomns, XElement entry, XNamespace medians)
{
var id = entry.Element(atomns.GetName("id")) != null && entry.Element(atomns.GetName("id")).Value != null
? entry.Element(atomns.GetName("id")).Value.Split(':').Last()
: string.Empty;
VideoUrl = "https://gdata.youtube.com/feeds/api/videos/" + id;
}
Обратите внимание: я нашел этот пост SO, в котором говорится о пространствах имен:
Использование LINQ to XML для обработки XML в нескольких пространствах имен а>
Меня беспокоит то, что, возможно, есть способ извлечь yt:videoid из XML без жесткого кодирования пространства имен yt в код, поскольку yt strong> находится прямо внутри элемента yt:videoid как атрибут xmlns. Есть ли метод, который выбирает узел пространства имен, который имеет ссылку на пространство имен в качестве атрибута? Если нет, то как правильно выбрать пространство имен из элемента, который несет его в качестве атрибута, и получить доступ к содержимому элемента пространства имен?
ОБНОВЛЕНИЕ: Чтобы обойти текущую проблему, я использую код ниже. Я все еще хотел бы узнать о решении, которое не игнорирует пространства имен, как это делает приведенный ниже код:
string videoid = (from child in entry.Descendants()
where child.Name.LocalName == "videoid"
select child.Value).FirstOrDefault();
ОБНОВЛЕНИЕ: теперь у меня есть запрос в стиле XPath, который не игнорирует работающие пространства имен, но он кажется немного многословным, и я хотел бы, чтобы кто-нибудь предложил более оптимизированный метод, если он есть. Я знаю, что мог бы добавить тернарные операторы, но вместо этого мне интересно, есть ли способ объединить разрешения пространства имен и выбор элемента?:
// Get the namespaces for the "media" group, since it contains the "yt" group,
// and for the "yt" group itself.
XNamespace xnsMediaGroup = entry.GetNamespaceOfPrefix("media");
XNamespace xnsYouTube = entry.GetNamespaceOfPrefix("yt");
// Got valid namespace references?
if ((xnsMediaGroup != null) && (xnsYouTube != null))
{
// Yes. Select the media group element.
XElement xelemMediaGroup = entry.Element(xnsMediaGroup.GetName("group"));
if (xelemMediaGroup != null)
{
// Select the YouTube videoid element.
XElement xelemYTVideoId = xelemMediaGroup.Element(xnsYouTube.GetName("videoid"));
if (xelemYTVideoId != null)
// Return the video's ID.
videoid = xelemYTVideoId.Value;
}
}