5

I am having problems with XPathNavigator. I have a document with a bunch of "topic" elements w/o namespace in a stream.

I am using (expression dumbed down to bare minimum, first I thought my expressions were wrong):

XPathDocument xmlDoc = new XPathDocument( stream );
XPathNavigator xml = xmlDoc.CreateNavigator();
XPathNodeIterator iter = xml.Select( "//topic" );

This doesn't work. I can select */*/* or something similar and get my "topic" elements alright. I tried running my expressions in online tester and other languages and they work.

Question: what's wrong? I have lingering suspicion that it has to do with accursed NamespaceManager object, which causes me incredible pain every time I parse document with namespaces, but this time the elements I am seeking don't have an explicit namespace! I added:

XmlNamespaceManager s = new XmlNamespaceManager( xml.NameTable ); 

and pass that as 2nd argument to Select - to no avail. How am I supposed to add "" namespace to this thing/use it correctly?

Or, better yet, is there way to use XPath in .NET without using this horrible abomination of the class, like in other languages? If I want namespaces, I can write them in the expression...

Update: I figured out a workaround- copy/paste default xmlns from root node, and then use that namespace:

thisIsRetarded.AddNamespace( "x", "urn:xmind:xmap:xmlns:content:2.0" );
XPathNodeIterator projectIter = projectTree.Select( "//x:topic", thisIsRetarded );

however, neither I am supposed to know the default URI, nor do I like to pollute my expressions with unnecessary x:-s. So I only need answer to 2nd part of the question now.

Sergey
  • 636
  • 6
  • 12
  • You _are_ supposed to know the namespaces. Two elements with the same name are _different_ if they are in different namespaces. – John Saunders Jan 11 '10 at 01:09
  • 1
    I'm sorry to say that naming a variable `thisIsRetarded` reveals just the wrong attitude for a programmer. Things are not retarded just because you fail to make sense of them. – Tomalak Jan 11 '10 at 09:14
  • 2
    But it *is* rather stupid if the element does not have a prefix in your xml document and you have to create some artificial construct in your xpath api to select it. – Brian Warshaw Oct 26 '10 at 13:17
  • Ha ha: "thisIsRetarded.AddNamespace..." +1 – bgmCoder May 04 '13 at 02:59

2 Answers2

4

I prefer to use XmlDocument:

XmlDocument doc = new XmlDocument();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("sample", "...");
doc.Load(stream);

XmlNode topic = doc.SelectSingleNode("/sample:topic", nsmgr);

// If you don't have any namespaces....
XmlNode topic2 = doc.SelectSingleNode("/topic"); 
Rubens Farias
  • 57,174
  • 8
  • 131
  • 162
0

Check this StackOverflow answer to the same problem with the explanation between the default namespace and no namespace: Xml-SelectNodes with default-namespace via XmlNamespaceManager not working as expected

And an even better explanation by Microsoft on how to use the default namespace: https://learn.microsoft.com/en-us/dotnet/standard/data/xml/xpath-queries-and-namespaces

Daniel Lobo
  • 2,144
  • 1
  • 13
  • 6