tags:

views:

63

answers:

2
+1  Q: 

XPath and *.csproj

I am for sure missing some important detail here. I just cannot make .NET's XPath work with Visual Studio project files.

Let's load an xml document:

var doc = new XmlDocument();
doc.Load("blah/blah.csproj");

Now execute my query:

var nodes = doc.SelectNodes("//ItemGroup");
Console.WriteLine(nodes.Count); // whoops, zero

Of course, there are nodes named ItemGroup in the file. Moreover, this query works:

var nodes = doc.SelectNodes("//*/@Include");
Console.WriteLine(nodes.Count); // found some

With other documents, XPath works just fine. I am absolutely puzzled about that. Could anyone explain me what is going on?

+4  A: 

Look at the root namespace; you'll have to include an xml-namespace manager and use queries like "//x:ItemGroup", where "x" is your designated alias for the root namespace. And pass the manager into the query. For example:

        XmlDocument doc = new XmlDocument();
        doc.Load("my.csproj");

        XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
        mgr.AddNamespace("foo", doc.DocumentElement.NamespaceURI);
        XmlNode firstCompile = doc.SelectSingleNode("//foo:Compile", mgr);
Marc Gravell
Adding a namespace did the trick. Pity that one cannot accept two answers for a question :-)
catbert
@catbert: you can reverse your currently-accepted answer (which is wrong), and accept the correct (@Marc-Gravell 's answer). Not only you can, but you `should` do so, because otherwise some people will think that the wrong/accepted answer is correct.
Dimitre Novatchev
+1 This is rigth.
Alejandro
A: 

You probably need to add a reference to the namespace http://schemas.microsoft.com/developer/msbuild/2003.

I had a similar problem, I wrote about it here. Do something like this:

XmlDocument xdDoc = new XmlDocument();
xdDoc.Load("blah/blah.csproj");

XmlNamespaceManager xnManager =
 new XmlNamespaceManager(xdDoc.NameTable);
xnManager.AddNamespace("tu",
 "http://schemas.microsoft.com/developer/msbuild/2003");

XmlNode xnRoot = xdDoc.DocumentElement;
XmlNodeList xnlPages = xnRoot.SelectNodes("//tu:ItemGroup", xnManager);
Naeem Sarfraz
which can't **possibly** work, since you haven't *used* the alias anywhere...
Marc Gravell
This is wrong...
Alejandro
yep, I missed the alias in the xpath
Naeem Sarfraz