XPath and XML Namespaces

It’s great that in C# code you can easily reference XML nodes using the XmlDocument’s built-in XPath support:

XmlNode titleNode = doc.SelectSingleNode("/html/head/title");

But have you ever run into the situation where you call SelectSingleNode or SelectNodes and you get back nothing when you can see there are nodes there? The problem might be that the document is using XML Namespaces.

Consider this XML snippet:

<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">
<url>
<loc>http://blog.stevex.net/</loc>
</url>
</urlset>

If you attempt to retrieve nodes from this document using this code:

XmlNode urlNodes = doc.SelectNodes("/urlset/url");

You might expect to get back a set of all the url nodes, but instead you get back nothing.

To query into a document that uses namespaces, you need to use an XmlNamespaceManager. The namespace manager takes care of mapping a prefix to a namespace, and lets you associate the nodes in the query with particular namespaces.

The following code would query the sitemap.xml:

XmlNamespaceManager nsMgr = new XmlNamespaceManager(myXmlDoc.NameTable);
nsMgr.AddNamespace("sm", "http://www.google.com/schemas/sitemap/0.84");
XmlNode urlNodes = doc.SelectNodes("/sm:urlset/sm:url");

If a page uses multiple namespaces then you’d have multiple calls to AddNamespace with different prefixes. Your query string can include nodes from different namespaces.

9 Responses to “XPath and XML Namespaces”

  1. Martin Says:

    Thank you!! I have been struggling with this for a couple of hours and now (at last!) it is working!

  2. Makarad Says:

    I am having similar problem but by xml doc is having 2 namespace attributes as given below

    What should be XmlNamespaceManager for this one?

    Thanks
    MAKARAND

  3. SvendTofte Says:

    This was just what I needed to know. I have a document similar to this one, the documentation claims you can use “String.Empty”, for a default namespace (and thus, I assumed not need prefixes in the actual xpath expression).

    Thanks, was just about to waste another hour on this non-issue ;)

  4. Christian Palm Says:

    I think you have a typo in your example

    You write:
    XmlNamespaceManager nsMgr = new XmlNamespaceManager(myXmlDoc.NameTable);
    It shoud be, I think:
    XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);

  5. Brad Candell Says:

    Thank you SO MUCH.. I was about to give up all together on these stupid Namespaces! I found your document and had my code working within mere minutes..

    Thanks again!

    -Brad

  6. Lee Says:

    THANK YOU THANK YOU THANK YOU THANK YOU. You saved me from /wrists. I’ve been looking and looking at my XPath and KNEW it was right. I had no idea that the namespace would muck things up.

    Thanks again,
    Lee

  7. XML, XPath and XML Namespaces oh my… | The Sexy Gorilla Says:

    [...] was just about to /mywrists today when I found this post. I wanted to post to this blog to say thanks to SteveX for posting [...]

  8. joey Says:

    thanks for the info:

    my code required a different implementation…
    XmlNodeList urlLocNode = sitemap.SelectNodes(”/sm:urlset/sm:url/sm:loc”, nsMgr);

    1) SelectNodes returns a XmlNodeList not an XmlNode

    2) You need to use the overloaded version of the SelectNodes method to pass the XmlNamespaceManager object.

  9. XML, XPath and XML Namespaces oh my… « Everything I do Makes Me a Bitweiser Says:

    [...] XPath and XML Namespaces oh my… I was just about to /mywrists today when I found this post. I wanted to post to this blog to say thanks to SteveX for posting [...]

Leave a Reply