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:
<foo xmlns="uri" />
It appears as though some of the XPath processor libraries won't recognize //foo
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.
Is there a standard that applies to this?
My approach is a bit hackish but it seems to work fine; I remove the xmlns
declaration with a search/replace and then apply XPath.
string readyForXpath = Regex.Replace(xmldocument, "xmlns=\".+\"", String.Empty );
Is that a fair approach or has anyone solved this differently?
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.
XPath stands for XML Path Language. It uses a non-XML syntax to provide a flexible way of addressing (pointing to) different parts of an XML document. It can also be used to test addressed nodes within a document to determine whether they match a pattern or not.
In XML a namespace is a collection of names used for elements and attributes. A URI (usually, a URL) is used to identify a particular collection of names.
You need local-name():
http://www.w3.org/TR/xpath#function-local-name
To crib from http://web.archive.org/web/20100810142303/http://jcooney.net:80/archive/2005/08/09/6517.aspx:
<foo xmlns='urn:foo'>
<bar>
<asdf/>
</bar>
</foo>
This expression will match the “bar” element:
//*[local-name()='bar']
This one won't:
//bar
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:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlWithBogusNamespace);
XmlNamespaceManager nSpace = new XmlNamespaceManager(doc.NameTable);
nSpace.AddNamespace("myNs", "http://theirUri");
XmlNodeList nodes = doc.SelectNodes("//myNs:NodesIWant",nSpace);
//etc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With