<p>What is the story behind XPath and support for namespaces? Did XPath as a specification precede namespaces?  If I have a document where elements have been given a default namespace: </p>

<pre><code>&lt;foo xmlns="uri" /&gt;
</code></pre>

<p>It appears as though some of the XPath processor libraries won't recognize <code>//foo</code> because of the namespace whereas others will. The option my team has thought about is to add a namespace prefix using regular expressions to the XPath (you can add a namespace prefix via XmlNameTable) but this seems brittle since XPath is such a flexible language when it comes to node tests.</p>

<p>Is there a standard that applies to this?</p>

<p>My approach is a bit hackish but it seems to work fine; I remove the <code>xmlns</code> declaration with a search/replace and then apply XPath.</p>

<pre><code>string readyForXpath = Regex.Replace(xmldocument, "xmlns=\".+\"", String.Empty );
</code></pre>

<p>Is that a fair approach or has anyone solved this differently?</p>

[{'answer_id': 11351, 'author': 'Stu', 'author_id': 414, 'author_profile': 'https://Stackoverflow.com/users/414', 'pm_score': 4, 'selected': False, 'text': '<p>You need local-name():</p>\n<p><a href="http://www.w3.org/TR/xpath#function-local-name" rel="nofollow noreferrer">http://www.w3.org/TR/xpath#function-local-name</a></p>\n<p>To crib from <a href="http://web.archive.org/web/20100810142303/http://jcooney.net:80/archive/2005/08/09/6517.aspx" rel="nofollow noreferrer">http://web.archive.org/web/20100810142303/http://jcooney.net:80/archive/2005/08/09/6517.aspx</a>:</p>\n<pre><code>&lt;foo xmlns=\'urn:foo\'&gt;\n  &lt;bar&gt;\n    &lt;asdf/&gt;\n  &lt;/bar&gt;            \n&lt;/foo&gt;\n</code></pre>\n<p>This expression will match the “bar” element:</p>\n<pre><code>  //*[local-name()=\'bar\'] \n</code></pre>\n<p>This one won\'t:</p>\n<pre><code> //bar\n</code></pre>\n'}, {'answer_id': 11370, 'author': 'palehorse', 'author_id': 312, 'author_profile': 'https://Stackoverflow.com/users/312', 'pm_score': 0, 'selected': False, 'text': '<p>If you are trying to use xslt you can add the namespace in to the stylesheet declaration.  If you do that, you must make sure that there is a prefix or it will not work.  If the source XML does not have a prefix, that is still fine, you add your own prefix in the stylesheet.  </p>\n\n<p><em>Stylesheet</em></p>\n\n<pre><code>&lt;xsl:stylesheet\n    xmlns:fb="uri"\n    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;\n\n    &lt;xsl:template match="fb:foo/bar"&gt;\n        &lt;!--  do stuff here --&gt;\n    &lt;/xsl:template&gt;\n&lt;/xsl:stylsheet&gt;\n</code></pre>\n\n<p>Or something like that.</p>\n'}, {'answer_id': 16294, 'author': 'samjudson', 'author_id': 1908, 'author_profile': 'https://Stackoverflow.com/users/1908', 'pm_score': 2, 'selected': False, 'text': "<p>The issue is that an element without a namespace is declared to be in the NULL namespace - therefore if //foo matched against the namespace you consider to be the 'default' there would be no way to refer to an element in the null namespace.</p>\n\n<p>Remember as well that the prefix for a namespace is only a shorthand convention, the real element name (Qualified Name, or QName for short) consists of the full namespace and the local name. Changing the prefix for a namespace does not change the 'identity' of an element - if it is in the same namespace and same local name then it is the same kind of element, even if the prefix is different.</p>\n\n<p>XPath 2.0 (or rather XSLT 2.0) has the concept of the 'default xpath namespace'. You can set the xpath-default-namespace attribute on the xsl:stylesheet element.</p>\n"}, {'answer_id': 149088, 'author': 'Andrew Cowenhoven', 'author_id': 12281, 'author_profile': 'https://Stackoverflow.com/users/12281', 'pm_score': 4, 'selected': True, 'text': '<p>I tried something similar to what palehorse proposed and could not get it to work. Since I  was getting data from a published service I couldn\'t change the xml. I ended up using XmlDocument and XmlNamespaceManager like so:</p>\n\n<pre><code>XmlDocument doc = new XmlDocument();\ndoc.LoadXml(xmlWithBogusNamespace);            \nXmlNamespaceManager nSpace = new XmlNamespaceManager(doc.NameTable);\nnSpace.AddNamespace("myNs", "http://theirUri");\n\nXmlNodeList nodes = doc.SelectNodes("//myNs:NodesIWant",nSpace);\n//etc\n</code></pre>\n'}, {'answer_id': 49044337, 'author': 'crazy dev', 'author_id': 9427549, 'author_profile': 'https://Stackoverflow.com/users/9427549', 'pm_score': 0, 'selected': False, 'text': '<p>Using libxml it seems this works:</p>\n\n<p><a href="http://xmlsoft.org/examples/xpath1.c" rel="nofollow noreferrer">http://xmlsoft.org/examples/xpath1.c</a></p>\n\n<pre><code> int \nregister_namespaces(xmlXPathContextPtr xpathCtx, const xmlChar* nsList) {\n    xmlChar* nsListDup;\n    xmlChar* prefix;\n    xmlChar* href;\n    xmlChar* next;\n\n    assert(xpathCtx);\n    assert(nsList);\n\n    nsListDup = xmlStrdup(nsList);\n    if(nsListDup == NULL) {\n    fprintf(stderr, "Error: unable to strdup namespaces list\\n");\n    return(-1); \n    }\n\n    next = nsListDup; \n    while(next != NULL) {\n    /* skip spaces */\n    while((*next) == \' \') next++;\n    if((*next) == \'\\0\') break;\n\n    /* find prefix */\n    prefix = next;\n    next = (xmlChar*)xmlStrchr(next, \'=\');\n    if(next == NULL) {\n        fprintf(stderr,"Error: invalid namespaces list format\\n");\n        xmlFree(nsListDup);\n        return(-1); \n    }\n    *(next++) = \'\\0\';   \n\n    /* find href */\n    href = next;\n    next = (xmlChar*)xmlStrchr(next, \' \');\n    if(next != NULL) {\n        *(next++) = \'\\0\';   \n    }\n\n    /* do register namespace */\n    if(xmlXPathRegisterNs(xpathCtx, prefix, href) != 0) {\n        fprintf(stderr,"Error: unable to register NS with prefix=\\"%s\\" and href=\\"%s\\"\\n", prefix, href);\n        xmlFree(nsListDup);\n        return(-1); \n    }\n    }\n\n    xmlFree(nsListDup);\n    return(0);\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/11345', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/64/']