I think you have typos there. However, take a look at this solution:
var text = @"
<main id='AFB' rank='1' name='ROOT'>
<sub id='DFG' rank='2' name='SUB1'>
<opt>
<sel id='JIK' rank='4' name='444' />
<sel id='OKI' rank='2' name='222' />
</opt>
<opt>
<sel id='JIK' rank='2' name='122' />
<sel id='OKI' rank='1' name='111' />
</opt>
</sub>
<sub id='EGG' rank='1' name='SUB2' >
<opt>
<sel id='DJI' rank='1' name='111' />
<sel id='LOW' rank='3' name='333' />
<sel id='QWE' rank='2' name='222' />
</opt>
</sub>
</main>";
var x = XDocument.Parse(text);
x.Root.ReplaceNodes(x.Descendants("sub").OrderBy(a => int.Parse(a.Attribute("rank").Value)));
foreach (var opt in x.Descendants("opt"))
opt.ReplaceNodes(opt.Descendants("sel").OrderBy(a => int.Parse(a.Attribute("rank").Value)));
At this point, it xcontains the following XML:
<main id="AFB" rank="1" name="ROOT">
<sub id="EGG" rank="1" name="SUB2">
<opt>
<sel id="DJI" rank="1" name="111" />
<sel id="QWE" rank="2" name="222" />
<sel id="LOW" rank="3" name="333" />
</opt>
</sub>
<sub id="DFG" rank="2" name="SUB1">
<opt>
<sel id="OKI" rank="2" name="222" />
<sel id="JIK" rank="4" name="444" />
</opt>
<opt>
<sel id="OKI" rank="1" name="111" />
<sel id="JIK" rank="2" name="122" />
</opt>
</sub>
</main>
If attthere is instead of "opt" and should be enabled, the following will work:
var x = XDocument.Parse(text);
x.Root.ReplaceNodes(x.Descendants("sub").OrderBy(a => int.Parse(a.Attribute("rank").Value)));
foreach (var opt in x.Descendants("sub").Elements())
opt.ReplaceNodes(opt.Descendants("sel").OrderBy(a => int.Parse(a.Attribute("rank").Value)));
, ( , ):
var sub2 = x.Descendants("sub").FirstOrDefault(a => a.Attribute("id").Value == "EGG");
if (sub2 != null)
{
foreach (var node in sub2.Elements())
node.ReplaceNodes(node.Elements().OrderBy(a =>
{
int rank;
if (a.Attribute("rank") == null || !int.TryParse(a.Attribute("rank").Value, out rank))
rank = int.MaxValue;
return rank;
}));
}