简体   繁体   English

带命名空间的XML的XPath

[英]XPath for XML with namespace

I have an xml with various namespaces that i would like to query using .SelectNodes(string xPath) 我有一个带有各种命名空间的xml,我想使用它来查询.SelectNodes(string xPath)

The problem that i notice is that the xPath query return nothing as long as i have all those namespaces around. 我注意到的问题是,只要我拥有所有这些名称空间,xPath查询就不会返回任何内容。

  1. is there anyway to tell XmlDocument.SelectNodes to ignore those namespaces and just get me the correct elements (the elements that i query doesn't seem to have namespaces prefix)? 无论如何告诉XmlDocument.SelectNodes忽略这些命名空间,只是给我正确的元素(我查询的元素似乎没有名称空间前缀)?

  2. if there is, can anyone please provide me an example of how to do it? 如果有,有谁可以请我提供一个如何做的例子? what should i defined before/when i query the nodes? 我在查询节点之前/当我应该定义什么?

Thanks for the help. 谢谢您的帮助。

Correction: i still can't figure what the problem is. 更正:我仍然无法确定问题所在。 here is my xml: 这是我的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>

and here is my code: 这是我的代码:

XmlDocument xml = ExecuteRequest(url); 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);

and my nodes count is still 0! 我的节点数仍为0! any idea? 任何的想法?

You need to create a namespace manager, setup all the namespaces that you want to use and their prefix and then in the XPath, you need to use the prefix. 您需要创建命名空间管理器,设置要使用的所有命名空间及其前缀,然后在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);

Warning: I did not compile this code. 警告:我没有编译此代码。

I'm not as familiar with the .NET api, but you might be able to send in a more generic XPATH that ignores namespaces by matching on any element(eg * ) and using the local-name in the predicate filters. 我对.NET api并不熟悉,但您可以通过匹配任何元素(例如* )并在谓词过滤器中使用local-name来发送更通用的XPATH来忽略命名空间。

eg using /*[local-name()='foo']/*[local-name()='bar']/*[local-name()='baz'] to find ns:foo/ns:bar/ns:baz without declaring the ns namespace. 例如,使用/*[local-name()='foo']/*[local-name()='bar']/*[local-name()='baz']来查找ns:foo/ns:bar/ns:baz没有声明ns命名空间。

That way you don't have to bind to a particular namespace at compile time and can pass in arbritrary XPATH statements. 这样,您不必在编译时绑定到特定的命名空间,并且可以传递arbritrary XPATH语句。

Obviously, by using namespace-unaware XPATH statements you could get unintended results(if there is mixed namespace content with elements of the same name) and the XPATH is really verbose. 显然,通过使用名称空间不知道的XPATH语句,您可能会得到意想不到的结果(如果存在具有相同名称的元素的混合名称空间内容),并且XPATH真的很冗长。

In XPATH 2.0 you can use wildcards for namespaces: /*:foo/*:bar/*:baz , but you would have to use Saxon to get XSLT/XPATH 2.0 support in .NET. XPATH 2.0中,您可以使用通配符作为名称空间: /*:foo/*:bar/*:baz ,但您必须使用Saxon在.NET中获得XSLT / XPATH 2.0支持。

found the problem in another post here: No Nodes Selected from Atom XML document using XPath? 在这里的另一篇文章中发现了这个问题: 没有使用XPath从Atom XML文档中选择节点?

thanks everybody. 谢谢大家。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM