I am trying to select all nodes using root.SelectNodes()
with XPath
. For reference, see msdn-documentation.
In the following document explained, you can also search for nodes that contain attributes (correct me if this is actually a wrong understanding).
So I used the following line of code:
XmlNodeList nodes = projectDoc.DocumentElement.SelectNodes("descendant::Compile[attribute::Include]");
And I am trying to read the following data:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<ItemGroup>
<Compile Include="ArrayExtensions.cs" />
<Compile Include="ArrayIterator.cs" />
<Compile Include="AutoInitializeAttribute.cs" />
<Compile Include="AutoInitializePriority.cs" />
<Compile Include="AutoRegisterAttribute.cs" />
<Compile Include="FormattableExtensions.cs" />
<Compile Include="Mathematics\PrimeNumbers.cs" />
</ItemGroup>
</Project>
As shown in the code-sample above, I want to get all the XmlNodes that contain the Include-attribute. However, when I execute my code, nodes
contains 0 elements.
What am I doing wrong here?
I suspect the reason it's failing has nothing to do with the attribute part - it's failing to find the elements at all, as you've asked for just Compile
elements, whereas there are only actually Compile
elements in the namespace with the URI http://schemas.microsoft.com/developer/msbuild/2003
.
Doing this with XPath probably requires the use of an XmlNamespaceManager
which you'd then pass into another overload of SelectNodes
. Personally I would use LINQ to XML instead though:
XDocument doc = XDocument.Load("myfile.xml");
XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
var elements = doc.Descendants(ns + "Compile")
.Where(x => x.Attribute("Include") != null);
In general, I find LINQ to XML to be a much cleaner API than the "old" XmlDocument
-based API.
See more on this question at Stackoverflow