【问题标题】:XPath for XML with namespace带有命名空间的 XML 的 XPath
【发布时间】:2011-01-05 18:07:30
【问题描述】:

我有一个带有各种命名空间的 xml,我想使用 .SelectNodes(string xPath) 进行查询

我注意到的问题是,只要我拥有所有这些命名空间,xPath 查询就不会返回任何内容。

  1. 有没有办法告诉 XmlDocument.SelectNodes 忽略那些命名空间,只给我正确的元素(我查询的元素似乎没有命名空间前缀)?

  2. 如果有的话,谁能给我一个如何做的例子?在查询节点之前/当我查询节点时我应该定义什么?

感谢您的帮助。

更正:我仍然无法弄清楚问题所在。这是我的 xml:

<feed xmlns="http://www.w3.org/2005/Atom"  xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"  xmlns:gf="http://schemas.google.com/finance/2007"  
      xmlns:gd="http://schemas.google.com/g/2005" >
  <id>http://finance.google.com/finance/feeds/xyx@google.com/portfolios</id>
  <updated>2009-12-15T19:32:21.000Z</updated>
  <category scheme="http://schemas.google.com/g/2005#kind"  term="http://schemas.google.com/finance/2007#portfolio" />
  <title type="text" >Portfolio Feed</title>
  <link rel="alternate"  type="text/html"  href="http://finance.google.com/finance/portfolio?action=view" />
  <link rel="http://schemas.google.com/g/2005#feed"  type="application/atom+xml"  href="http://finance.google.com/finance/feeds/default/portfolios" />
  <link rel="http://schemas.google.com/g/2005#post"  type="application/atom+xml"  href="http://finance.google.com/finance/feeds/default/portfolios" />
  <link rel="self"  type="application/atom+xml"  href="http://finance.google.com/finance/feeds/default/portfolios" />
  <openSearch:totalResults>24</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>24</openSearch:itemsPerPage>
  <entry>
    <id>http://finance.google.com/finance/feeds/xyx@google.com/portfolios/2</id>
    <updated>2009-12-14T16:26:53.000Z</updated>
    <category scheme="http://schemas.google.com/g/2005#kind"  term="http://schemas.google.com/finance/2007#portfolio" />
    <title type="text" >Main</title>
    <link rel="self"  type="application/atom+xml"  href="http://finance.google.com/finance/feeds/default/portfolios/2" />
    <link rel="edit"  type="application/atom+xml"  href="http://finance.google.com/finance/feeds/default/portfolios/2" />
    <gd:feedLink href="http://finance.google.com/finance/feeds/xyx@google.com/portfolios/2/positions" />
    <gf:portfolioData currencyCode="USD"  gainPercentage="0.0"  return1w="0.0"  return1y="0.0"  return3m="0.0"  return3y="0.0"  return4w="0.0"  return5y="0.0"  returnOverall="0.0"  returnYTD="0.0" />
  </entry>
</feed>

这是我的代码:

XmlDocument xml = ExecuteRequest(url);

        var xmlnsManager = new System.Xml.XmlNamespaceManager(xml.NameTable);
        xmlnsManager.AddNamespace("xmlns:openSearch", "http://a9.com/-/spec/opensearchrss/1.0/");
        xmlnsManager.AddNamespace("xmlns:gf", "http://schemas.google.com/finance/2007");
        xmlnsManager.AddNamespace("xmlns:gd", "http://schemas.google.com/g/2005");

        var nodes = xml.SelectNodes("//feed/entry", xmlnsManager);

我的节点数仍然是 0!有什么想法吗?

【问题讨论】:

    标签: .net xml xpath xmldocument


    【解决方案1】:

    您需要创建一个命名空间管理器,设置所有要使用的命名空间及其前缀,然后在 XPath 中,您需要使用前缀。

    var doc = new XmlDocument(); 
    doc.Load("myfile.xml");
    
    var xmlnsManager = new System.Xml.XmlNamespaceManager(doc.NameTable);
    xmlnsManager.AddNamespace("ns", "http://example.org/schema.xsd");
    
    doc.SelectNodes("//ns:MyElement",xmlnsManager);
    

    警告:我没有编译这段代码。

    【讨论】:

      【解决方案2】:

      我对 .NET api 不太熟悉,但您可以发送一个更通用的 XPATH,通过匹配任何元素(例如 *)并在谓词中使用 local-name 来忽略命名空间过滤器。

      例如使用/*[local-name()='foo']/*[local-name()='bar']/*[local-name()='baz'] 在不声明 ns 命名空间的情况下查找 ns:foo/ns:bar/ns:baz。

      这样您就不必在编译时绑定到特定的命名空间,并且可以传入任意 XPATH 语句。

      显然,通过使用不知道命名空间的 XPATH 语句,您可能会得到意想不到的结果(如果存在具有相同名称元素的混合命名空间内容)并且 XPATH 确实很冗长。

      在 XPATH 2.0 中,您可以对命名空间使用通配符:/*:foo/*:bar/*:baz,但您必须使用 Saxon 才能在 .NET 中获得 XSLT/XPATH 2.0 支持.

      【讨论】:

      【解决方案3】:

      在这里的另一篇文章中发现了问题: No Nodes Selected from Atom XML document using XPath?

      谢谢大家。

      【讨论】:

      • 仅链接的答案是糟糕的答案。您应该包括链接答案中的实质性内容。然而,在这种情况下,一旦你这样做了,你的答案将类似于Darrel Miller's answer above,在我看来,这应该是这里接受的答案,而不是你的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-22
      • 2012-06-09
      • 2011-11-07
      • 1970-01-01
      相关资源
      最近更新 更多