Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use XPath with a default namespace with no prefix?

What is the XPath (in C# API to XDocument.XPathSelectElements(xpath, nsman) if it matters) to query all MyNodes from this document?

<?xml version="1.0" encoding="utf-8"?> <configuration>   <MyNode xmlns="lcmp" attr="true">     <subnode />   </MyNode> </configuration> 
  • I tried /configuration/MyNode which is wrong because it ignores the namespace.
  • I tried /configuration/lcmp:MyNode which is wrong because lcmp is the URI, not the prefix.
  • I tried /configuration/{lcmp}MyNode which failed because Additional information: '/configuration/{lcmp}MyNode' has an invalid token.

EDIT: I can't use mgr.AddNamespace("df", "lcmp"); as some of the answerers have suggested. That requires that the XML parsing program know all the namespaces I plan to use ahead of time. Since this is meant to be applicable to any source file, I don't know which namespaces to manually add prefixes for. It seems like {my uri} is the XPath syntax, but Microsoft didn't bother implementing that... true?

like image 944
Scott Stafford Avatar asked Mar 26 '10 16:03

Scott Stafford


People also ask

What is XPath default namespace?

The Default NamespaceXPath treats the empty prefix as the null namespace. In other words, only prefixes mapped to namespaces can be used in XPath queries. This means that if you want to query against a namespace in an XML document, even if it is the default namespace, you need to define a prefix for it.

How do you define a default namespace for an XML document?

When you use multiple namespaces in an XML document, you can define one namespace as the default namespace to create a cleaner looking document. The default namespace is declared in the root element and applies to all unqualified elements in the document. Default namespaces apply to elements only, not to attributes.


1 Answers

The configuration element is in the unnamed namespace, and the MyNode is bound to the lcmp namespace without a namespace prefix.

This XPATH statement will allow you to address the MyNode element without having declared the lcmp namespace or use a namespace prefix in your XPATH:

/configuration/*[namespace-uri()='lcmp' and local-name()='MyNode'] 

It matches any element that is a child of configuration and then uses a predicate filer with namespace-uri() and local-name() functions to restrict it to the MyNode element.

If you don't know which namespace-uri's will be used for the elements, then you can make the XPATH more generic and just match on the local-name():

/configuration/*[local-name()='MyNode'] 

However, you run the risk of matching different elements in different vocabularies(bound to different namespace-uri's) that happen to use the same name.

like image 65
Mads Hansen Avatar answered Oct 14 '22 22:10

Mads Hansen