If node name is deprecated and must not be used in the whole document, just use ReplaceWith:
var xNode = doc.Descendants("x");
for (int i = 0; i < xNode.Count; i++)
{
xNode[i].ReplaceWith(xNode[i].Nodes());
}
To improve Mike's useful answer slightly.
The reason you can't just iterate Descendants
once is because AddAfterSelf()
creates copies. After the first removal you're iterating children of the removed element rather than their replacements in the document.
However, if you iterate them backwards, then any copied children will have already been processed, so you can get away with a single pass:
foreach(var x in xdoc.Descendants("x").Reverse())
{
x.AddAfterSelf(x.Nodes());
x.Remove();
}
var x = doc.Root.Element("X");
x.Remove();
doc.Root.Add(x.Elements());
Approved answer will always add children to the end of document. If you need to remove entry in the middle of the document and keep children where they sit, do following:
x.AddAfterSelf(x.Nodes());
x.Remove();
Following code removes all <x>
nodes keeping children in the correct place:
while (doc.Descendants("x").Count() > 0)
{
var x = doc.Descendants("x").First();
x.AddAfterSelf(x.Nodes());
x.Remove();
}