views:

305

answers:

3

Hi,

I have an xml with various namespaces that i would like to query using .SelectNodes(string xPath)

The problem that i notice is that the xPath query return nothing as long as i have all those namespaces around.

  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)?

  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:

<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/[email protected]/portfolios&lt;/id&gt;
  <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/[email protected]/portfolios/2&lt;/id&gt;
    <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/[email protected]/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);

        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! any idea?

+6  A: 

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.

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.

Darrel Miller
+1, compiles fine
Rubens Farias
A: 

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(e.g. *) and using the local-name in the predicate filters.

e.g. using /*[local-name()='foo']/*[local-name()='bar']/*[local-name()='baz'] to find ns:foo/ns:bar/ns:baz without declaring the ns namespace.

That way you don't have to bind to a particular namespace at compile time and can pass in arbritrary XPATH statements.

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.

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.

Mads Hansen
Actually, Altova have a free XSLT 2.0 processor that is COM based but could be accessed from .Net. (http://www.altova.com/altovaxml.html) and Intel recently released XSLT 2.0 processor that runs on 64bit windows. http://software.intel.com/en-us/articles/intel-soa-expressway-xslt-20-processor/
Darrel Miller
A: 

found the problem in another post here: http://stackoverflow.com/questions/501171/no-nodes-selected-from-atom-xml-document-using-xpath

thanks everybody.

Or A