How to make a deep copy of an element in LINQ to XML?

I want to make a deep copy of LINQ to XML XElement. The reason I want to do this is because some nodes in the document that I want to create modified copies (in the same document). I do not see a method for this.

I could convert the element to an XML string and then repeat it, but I am wondering if there is a better way.

+48
linq-to-xml
Oct. 16 '08 at 17:52
source share
5 answers

No need to rewrite. One of the XElement constructors takes another XElement and makes it deep:

XElement original = new XElement("original"); XElement deepCopy = new XElement(original); 

Here are a couple of unit tests to demonstrate:

 [TestMethod] public void XElementShallowCopyShouldOnlyCopyReference() { XElement original = new XElement("original"); XElement shallowCopy = original; shallowCopy.Name = "copy"; Assert.AreEqual("copy", original.Name); } [TestMethod] public void ShouldGetXElementDeepCopyUsingConstructorArgument() { XElement original = new XElement("original"); XElement deepCopy = new XElement(original); deepCopy.Name = "copy"; Assert.AreEqual("original", original.Name); Assert.AreEqual("copy", deepCopy.Name); } 
+97
Dec 10 '08 at 15:35
source share

It seems that the ToString and reparse method is the best way. Here is the code:

 XElement copy = XElement.Parse(original.ToString()); 
+6
Oct. 16 '08 at 18:17
source share

Raised directly from C # 3.0 in a nutshell :

When a node or attribute is added to an element (via a functional construct or the Add method), the node property or Parent attribute is set to this element. A node can have only one parent: if you add an already born node to the second parent, the node will automatically be deeply cloned. In the following example, each client has a separate copy of the address:

 var address = new XElement ("address", new XElement ("street", "Lawley St"), new XElement ("town", "North Beach") ); var customer1 = new XElement ("customer1", address); var customer2 = new XElement ("customer2", address); customer1.Element ("address").Element ("street").Value = "Another St"; Console.WriteLine ( customer2.Element ("address").Element ("street").Value); // Lawley St 

This automatic duplication saves an instance of the X-DOM object without any side effects - another sign of functional programming.

+2
Oct 17 '08 at 2:00
source share

This should work:

 var copy = new XElement(original.Name, original.Attributes(), original.Elements() ); 
0
Aug 16 '13 at 15:26
source share

I do not believe that there is an existing mechanism that allows you to make a deep copy of the XNode style tree. I think you have two options left.

  • Do as you suggested convert to string and then return to tree
  • Write to yourself with a visitor template.

A visitor template is certainly possible, but it will take a lot of work to test it. I think your best option is No. 1.

-2
Oct 16 '08 at 17:58
source share



All Articles