tags:

views:

778

answers:

3

Hi,

So I'm trying to parse the following XML document with C#, using System.XML:

<root xmlns:n="http://www.w3.org/TR/html4/"&gt;
 <n:node>
  <n:node>
   data
  </n:node>
 </n:node>
 <n:node>
  <n:node>
   data
  </n:node>
 </n:node>
</root>

Every treatise of XPath with namespaces tells me to do the following:

XmlNamespaceManager mgr = new XmlNamespaceManager(xmlDoc.NameTable);
mgr.AddNamespace("n", "http://www.w3.org/1999/XSL/Transform");

And after I add the code above, the query

xmlDoc.SelectNodes("/root/n:node", mgr);

Runs fine, but returns nothing. The following:

xmlDoc.SelectNodes("/root/node", mgr);

returns two nodes if I modify the XML file and remove the namespaces, so it seems everything else is set up correctly. Any idea why it work doesn't with namespaces?

Thanks alot!

+2  A: 

The URI you specified in your AddNamespace method doesn't match the one in the xmlns declaration.

Steven Sudit
+1  A: 

If you declare prefix "n" to represent the namespace "http://www.w3.org/1999/XSL/Transform", then the nodes won't match when you do your query. This is because, in your document, the prefix "n" refers to the namespace "http://www.w3.org/TR/html4/".

Try doing mgr.AddNamespace("n", "http://www.w3.org/TR/html4/"); instead.

Nader Shirazie
+2  A: 

As stated, it's the URI of the namespace that's important, not the prefix.

Given your xml you could use the following:

mgr.AddNamespace( "someOtherPrefix", "http://www.w3.org/TR/html4/" );
var nodes = xmlDoc.SelectNodes( "/root/someOtherPrefix:node", mgr );

This will give you the data you want. Once you grasp this concept it becomes easier, especially when you get to default namespaces (no prefix in source xml), since you instantly know you can assign a prefix to each URI and strongly reference any part of the document you like.

Timothy Walters
Thanks alot. It would have never occured to me that it was the URI that was significant, although it was still silly of me to miss such a glaring inconsistency.
Vercinegetorix
Yes, that's not very intuitive, but now that you know it, you know it.
Steven Sudit