Here's a recursive solution, the x List in the RecurseElements method is just there so you can see what Descendants look like compared to querying for them. You'll also need to adjust it to query whatever you need. I'm just pulling from a name attribute. Also, if you want to enforce a max depth of recursion, just add that to the if statement at the top:
using System.Linq;
using System.Xml.Linq;
using System.Collections.Generic;
private void RecurseElements(IEnumerable<XElement> descendants, int level)
{
if (descendants == null || !descendants.Any()) return;
foreach (var d in descendants)
{
string levelName = d.Attribute("name").Value;
System.Diagnostics.Debug.Print(string.Format("Level name {0}", levelName));
var x = d.Descendants().ToList();
var descendantElms = d.Descendants(string.Format("level{0}", level+1)).ToList();
RecurseElements(descendantElms, level+1);
}
}
Call above with something similar to:
XElement config = XElement.Parse(
@"<root>
<level1 name=""level1A"">
<level2 name=""level2A"">
<level3 name=""level3A"">
<level4 name=""level4A"">
<level5 name=""level5A"">
<level6 name=""level6A"">
<level7 name=""level7A"">
<level8 name=""level8A""></level8>
</level7>
</level6>
</level5>
</level4>
</level3>
</level2>
</level1>
<level1 name=""level1B"">
<level2 name=""level2B"">
<level3 name=""level3B"">
<level4 name=""level4B"">
<level5 name=""level5B"">
<level6 name=""level6B"">
<level7 name=""level7B"">
<level8 name=""level8B""></level8>
</level7>
</level6>
</level5>
</level4>
</level3>
</level2>
</level1>
</root>"
);
var descendants = config.Descendants("level1").ToList();
RecurseElements(descendants, 1);
Your debug output should look like this:
Level name level1A
Level name level2A
Level name level3A
Level name level4A
Level name level5A
Level name level6A
Level name level7A
Level name level8A
Level name level1B
Level name level2B
Level name level3B
Level name level4B
Level name level5B
Level name level6B
Level name level7B
Level name level8B