Disreguard my last solution as I did not read your XML properly. You are modifying the heirarchy of the tree, so you can use Decentants to seek it out. After seeking them you can place them in a duplicate XDocument.
After that you can put in the nodes they 'were' in minus the nodes that have been moved.
Bellow I have broken it down into 2 methods. One that reads the data in, and one that handles your reordering.
private void ReadXML()
{
_rawXML = XDocument.Load(PATH_INPUT);
_sortedXML = XDocument.Load(PATH_INPUT);
var nodesThatWillBeRepopulated = _sortedXML.Root.Elements(ELEMENT_SORT).ToList();
foreach (var node in nodesThatWillBeRepopulated)
{
node.Remove();
}
}
The first thing we do is get a compilation of all the nodes to be moved (with "System" in the "Name" field of element type "Common". Then we also grab the ones that are to not be moved but have the 'moved' ones removed from their node.
The loops do the actual work.
private void SortXML()
{
var moveThese = _rawXML.Root.Descendants(ELEMENT_SORT).Where(node => node.Attribute(ATTRIBUTE_COMP) != null && string.Equals(node.Attribute(ATTRIBUTE_COMP).Value, ATTRIBUTE_MOVE, StringComparison.CurrentCultureIgnoreCase));
var addTheseBackInLast = _rawXML.Root.Descendants(ELEMENT_SORT).Where(node => node.Attribute(ATTRIBUTE_COMP) != null && string.Equals(node.Attribute(ATTRIBUTE_COMP).Value, ATTRBITE_SEEK, StringComparison.CurrentCultureIgnoreCase));
foreach (var node in moveThese)
{
_sortedXML.Root.Add(new XElement(node));
}
foreach (var node in addTheseBackInLast)
{
var removeThese = node.Descendants(ELEMENT_SORT).Where(element => element.Attribute(ATTRIBUTE_COMP) != null && string.Equals(element.Attribute(ATTRIBUTE_COMP).Value, ATTRIBUTE_MOVE, StringComparison.CurrentCultureIgnoreCase)).ToList();
foreach (var removeThis in removeThese)
{
removeThis.Remove();
}
_sortedXML.Root.Add(new XElement(node));
}
}
And here are the constants I was using (hardcoded to your XML data)
private const string ATTRIBUTE_MOVE = "System";
private const string ELEMENT_SORT = "Common";
private const string ATTRBITE_SEEK = "Man";
private const string ATTRIBUTE_COMP = "Name";
private XDocument _rawXML;
private XDocument _sortedXML;
Let me know if you do not understand something.