Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XPath for XML with namespace

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</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/[email protected]/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/[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?

like image 356
Or A Avatar asked Jan 16 '10 00:01

Or A


People also ask

How do I find the XPath namespace?

There is no method to connect a namespace prefix to a namespace in XPath. The hosting library can provide these services. It is strongly advised that we take advantage of those features and create namespace prefixes that may be used to qualify XML element and attribute names as needed.

How do I find the XML namespace?

XML Namespaces - The xmlns Attribute When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax. xmlns:prefix="URI".

What is namespace node in XPath?

XPath defines a way to compute a string-value for each type of node. Some types of nodes also have names. XPath fully supports XML Namespaces. Thus, the name of a node is modeled as a pair consisting of a local part and a possibly null namespace URI; this is called an expanded-name.

Can XML attributes have namespaces?

An XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies element names uniquely on the Web in order to avoid conflicts between elements with the same name.


2 Answers

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.

like image 64
Darrel Miller Avatar answered Sep 21 '22 14:09

Darrel Miller


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.

like image 22
Mads Hansen Avatar answered Sep 22 '22 14:09

Mads Hansen