Linq to XML infanticide. Is there an easy way to promote grandchildren to replace children?

Consider the following snippet

using System; using System.Xml.Linq; class Program { static void Main() { var family = XDocument.Parse("<p><c><g/></c></p>"); var usurper = family.Root.Descendants("g"); family.Root.Element("c").Remove(); family.Root.Add(usurper); Console.WriteLine(family.ToString()); Console.ReadKey(); } } 

The output I get is @"<p />" , but I would like @"<p><g/></p>" . I can understand why this is happening, and there is justice, but this is not the result that I need.

If you change the order of the lines to

  var usurper = family.Root.Descendants("g"); family.Root.Add(usurper); family.Root.Element("c").Remove(); 

a circular connection is established, and as a result of removing the event OutOfMemoryException

Is there a simple, practical way to make this work?

EDIT

The fix that I really performed was

  var usurper = family.Root.Descendants("g").Single(); family.Root.Element("c").Remove(); family.Root.Add(usurper); 

Sorry my redness.

+4
source share
2 answers

Try to do it instead

 var usurper = family.Root.Descendants("g").ToList(); 

You need to force the enumeration to give a result due to lazy evaluation, otherwise you will get an empty result.

+5
source

I believe that you need to call usurper.Remove() before adding it to the Root element. Without this step, the usurper will always be a descendant of the c element, and therefore, when the c is removed, the usurper will be.

0
source

Source: https://habr.com/ru/post/1412623/


All Articles