XPath and XML Namespaces

Using XPath to extract nodes from some arbitary XML is quite a simple process - except, in my experience, if the given XML uses namespaces. For example, I have a simple library which takes an XML document and invokes a stored procedure, pulling out configurable values from the XML for the stored proc arguments:

var node = xml.SelectSingleNode(argXPath);
if (node == null) return "";
return node.InnerText;

However, when the XML has a namespace, this doesn't work quite so easily:

<m:message xmlns:m="http://www.sample.org/message">
 <m:header><m:id>message-1</m:id><m:system>SampleSystem</m:system></m:header>
 <body>This is the message content.</body>
</m:message>

To extract the id 'message-1', ignoring the namespace, the complete XPath to the id node is simply /message/header/id. But given the XML above, this XPath doesn't return anything.

One fix is to update the code, adding in a namespace manager:

var namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("m", "http://www.sample.org/message");
var node = xml.SelectSingleNode(argXPath, namespaceManager);

And the XPath is then /m:message/m:header/m:id.

Ignoring the Namespace

This is all well and good, but I didn't really want to change the library to add the namespace, so went on the lookout for an alternative. Of course, I found the answer on Stackoverflow:

/*[local-name()='message']/*[local-name()='header']/*[local-name()='id']

It's a bit of a mess and getting into regular expression category, but does exactly what I want. No need to change any code.


Comment Guidelines
See the FAQ for details on the full rules and guidelines. No Spam. Write clearly and thoughtfully - no bad language.