c# - 如何使用 C# (XNamespace/XElement) 导航 XML 文档

标签 c# xml linq youtube namespaces

我在检索 YouTube 数据馈送的 C# Windows Phone 8 应用程序中提取所需元素时遇到问题。 XML 文档如下所示。它来自 YouTube 播放列表提要:

<entry gd:etag="W/&quot;YDwqeyM.&quot;" xmlns:gd="http://schemas.google.com/g/2005" xmlns="http://www.w3.org/2005/Atom">
  <media:group xmlns:media="http://search.yahoo.com/mrss/">
    <media:category label="Science &amp; Technology" scheme="http://gdata.youtube.com/schemas/2007/categories.cat">Tech</media:category>
    <media:content url="https://www.youtube.com/v/vt7PLhQKYlU?version=3&amp;f=playlists&amp;app=youtube_gdata" type="application/x-shockwave-flash" medium="video" isDefault="true" expression="full" duration="1668" yt:format="5" xmlns:yt="http://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="http://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="http://gdata.youtube.com/schemas/2007" />
    <media:credit role="uploader" scheme="urn:youtube" yt:display="TheDigitalDigest" yt:type="partner" xmlns:yt="http://gdata.youtube.com/schemas/2007">thedigitaldigest</media:credit>
    <media:description type="plain">Surface 2</media:description>
    <yt:videoid xmlns:yt="http://gdata.youtube.com/schemas/2007">vt7PLhQKYlU</yt:videoid>
  </media:group>
</entry>

我需要修改下面使用 XNamespace/XElement 方法解析条目的代码以查找 yt:视频元素而不是 身份证 元素。我可以毫无困难地访问没有命名空间前缀的元素(那些不包含冒号的元素)。这是我需要修改的代码:
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 = "http://gdata.youtube.com/feeds/api/videos/" + id;
    }

请注意,我发现这篇 SO post 讨论了命名空间:

Using LINQ to XML to Process XML in Multiple Namespaces

我担心的是可能有办法退出 yt:videoid 从没有硬编码的 XML yt 命名空间进入代码,因为 yt 命名空间位于 内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;
            }
        }

最佳答案

我认为你应该阅读 Scott Hanselman 的文章:Get namespaces from an XML Document with XPathDocument and LINQ to XML

关于c# - 如何使用 C# (XNamespace/XElement) 导航 XML 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20205970/

相关文章:

asp.net-mvc - 如何在 Onion 架构中使用来自 Kendo UI 的 ToDataSourceResult 而不暴露 IQueryable

c# - 使用 LINQ 解析 HTML

c# - 如何将多个程序集合并为一个程序集?

xml - JAXB xjc - [错误] 意外 <xs :schema> appears at line 2 column 101

java - 如何创建表示对象的 XML 属性

xml - 具有可选条件的XPath查询(仅在标记存在时才应用条件)

c# - 使用 Fluent API 创建的 Entity Framework Core 2 一对多

c# - 从所有程序集中在 CaSTLe Windsor 容器中以编程方式注册所有 Controller

c# - 如何将程序集标记为过时

c# - 测试显示 "await"明显更慢,即使等待的对象已经完成