【问题标题】:How do you handle arbitrary namespaces when querying over Linq to XML?通过 Linq to XML 查询时如何处理任意命名空间?
【发布时间】:2008-10-08 15:29:34
【问题描述】:

我有一个项目,我在其中使用一些特别丑陋的“实时”HTML,并使用 HTML Agility Pack 将其强制转换为正式的 XML DOM。然后我想要做的是使用 Linq to XML 查询这个,以便我可以刮出我需要的位。我正在使用here 描述的方法将 HtmlDocument 解析为 XDocument,但是在尝试对此进行查询时,我不确定如何处理命名空间。在一个特定的文档中,原始 HTML 实际上是带有以下标记的格式不佳的 XHTML:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

当试图从这个文档中查询时,似乎命名空间属性阻止了我做类似的事情:

var x = xDoc.Descendants("div");
// returns null

显然,对于那些“div”标签,只有 LocalName 是“div”,但正确的标签名称是命名空间加上“div”。我曾尝试对 XML 命名空间的问题进行一些研究,似乎可以通过这种方式查询绕过命名空间:

var x = 
    (from x in xDoc.Descendants()
     where x.Name.LocalName == "div"
     select x);
// works

但是,这似乎是一个相当老套的解决方案,并不能正确解决命名空间问题。据我了解,一个正确的 XML 文档可以包含多个名称空间,因此处理它的正确方法应该是解析出我正在查询的名称空间。有没有其他人不得不这样做?我只是让它变得复杂吗?我知道我可以通过坚持使用 HtmlDocument 并使用 XPath 查询来避免这一切,但如果可能的话,我宁愿坚持我所知道的(Linq),我也更愿意知道我没有为进一步的命名空间做准备——未来的相关问题。

在这种情况下处理命名空间的正确方法是什么?

【问题讨论】:

    标签: html xml linq namespaces linq-to-xml


    【解决方案1】:

    使用LocalName 应该没问题。如果您不在乎它在哪个命名空间中,我根本不会认为它是 hack。

    如果你知道你想要的命名空间并且你想指定它,你可以:

    var ns = "{http://www.w3.org/1999/xhtml}";
    var x  = xDoc.Root.Descendants(ns + "div");
    

    (MSDN reference)

    您还可以获取文档中使用的所有命名空间的列表:

    var namespaces = (from x in xDoc.Root.DescendantsAndSelf()
                      select x.Name.Namespace).Distinct();
    

    我想你可以用它来做到这一点,但它并不是真正的黑客:

    var x = namespaces.SelectMany(ns=>xDoc.Root.Descendants(ns+"div"));
    

    【讨论】:

    • 这是关于 XLINQ API 最烦人的事情 :(。最好有办法告诉它忽略命名空间,或者至少指定一个默认值。
    【解决方案2】:

    如果您知道命名空间将由 XML 的根元素声明,通常情况下,您可以这样做:

    var ns = xDoc.Root.Name.Namespace;
    var x = xDoc.Descendants(ns + "div");
    

    【讨论】:

      【解决方案3】:

      我认为你的 Google-fu 让你失望了:

      http://www.google.com.au/search?hl=en&q=linq+xml+namespaces

      【讨论】:

      • 不。在前十个链接中的任何一个中向我展示一个真实示例,该示例描述了您事先不知道命名空间的情况。
      猜你喜欢
      • 1970-01-01
      • 2020-04-06
      • 1970-01-01
      • 1970-01-01
      • 2011-09-05
      • 2018-05-21
      • 2012-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多