Prasath Govind Prasath Govind - 1 month ago 11
C# Question

How to fetch some specific XML nodes present only in few parents using LINQ for XML?

I have been struggling to fetch some specific nodes of my XML.
Problem is that the node may or may not be present in the nth level.
I have shared my XML below :

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>

<Filter Include="Source Files - BT">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>

<Filter Include="Source Files - BT\TreeViewsnTraversals">
<UniqueIdentifier>{b685be7e-9d62-4f78-817c-def75db39d24}</UniqueIdentifier>
</Filter>
</ItemGroup>

<ItemGroup>
<ClCompile Include="..\4_Trees\SizeofBTree_Iterative.cpp">
<Filter>Source Files - BT\TreeProperties</Filter>
</ClCompile>
<ClCompile Include="..\4_Trees\SizeofBTree_Recursive.cpp">
<Filter>Source Files - BT\TreeProperties</Filter>
</ClCompile>
<ClCompile Include="..\4_Trees\LevelOrder_Left2Right.cpp">
<Filter>Source Files - BT\TreeViewsnTraversals</Filter>
</ClCompile>
<ClCompile Include="..\4_Trees\LevelOrder_Right2Left.cpp">
<Filter>Source Files - BT\TreeViewsnTraversals</Filter>
</ClCompile>
<ClCompile Include="..\4_Trees\PrintLeaftoNode.cpp">
<Filter>Source Files - BT\TreeViewsnTraversals</Filter>
</ClCompile>
<ClCompile Include="..\4_Trees\VerticalOrderSUM.cpp">
</ItemGroup>
</Project>


How to fetch only the "ClCompile" nodes (along with the corresponding "Filter" nodes)

As you can see, This is ClCompile is present as a descendant node for "ItemGroup" and ItemGroup may or may not contain ClCompile.

I tried to use LINQ for XML in C# syntax and I failed!

XElement filterxml = XElement.Load(filterfilepath);
var sourcefiles = filterxml.Elements("Project").Elements("ItemGroup").Elements("ClCompile");


How to go about this?

L.B L.B
Answer

Just don't forget to use the default xml namespace

var xDoc = XDocument.Load(filename);
XNamespace ns = xDoc.Root.GetDefaultNamespace();
//OR XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";

var nodes = xDoc.Descendants(ns + "ClCompile").ToList();

To get the Filter element, all you need is

var filter = nodes[i].Element(ns + "Filter");