简体   繁体   中英

Deep Copy of XDocument/Element with associated XElement (s)

Ok I have a XDocument

BaseDocument = XDocument.Load(@".\Example\Template.xml");

and some DataStructure of XElements (inside the XDocument) that gets generated by a method. This is just an example:

Dictionary<string, List<XElement>> ElementMap = GetElementMapping(BaseDocument);

I want to make a deep copy of both,

Is there a more efficient way than,

XDocument copy = new XDocument(BaseDocument);
Dictionary<string, List<XElement>> copyElementMap = GetElementMapping(copy);

to copy the datastructure so that the XElements inside reference the new copy?

I made some pictures to show what I want:

Current Solution: 复制与再生

I-Want Solution: 全部复制

As far as the XDocument copy you make is concearned, then we know that for sure it is as fast as we can go, as we can see from the documentation at line 2320 . This does a deep copy the way we want it to do.

If you need to do a deep copy of the XDocument object, then the above is the best way to go with regards to performance. It performs a deep copy of every node in the document (including XElements, XAttributes, comments etc.) without having to reload the file. It reads and clones all nodes while in-memory. This is an efficient operation, and it is the most efficient we can have, as it automatically suppresses all notification events that are normally fired internally in the XDocument. The deep copy can be verified from the below:

XML used:

<?xml version="1.0" encoding="utf-8" ?>
<FirstNode>
  <ChildNode attributeOne="1"/>
</FirstNode>

Source code

XDocument xDoc = XDocument.Load("AnXml.xml");
XDocument copy = new XDocument(xDoc);

Console.WriteLine("xDoc before change copy: {0}", xDoc.ToString());

copy.Root.Add(new XElement("NewElement", 5));
copy.Element("FirstNode").Element("ChildNode").Attribute("attributeOne").SetValue(2);
Console.WriteLine("xDoc after change copy: {0}", xDoc.ToString());
Console.WriteLine("copy after change copy: {0}", copy.ToString());

Console.ReadKey();

The two calls to Console.WriteLine output different values indicating that the two references point to different items with different structure, proving that a deep copy was made.

Note that if you want to re-use the XElements you have, there is no way to set them into XDocument without using reflection: all public methods to set XElements in an XDocument perform a deep copy. This is evident from the link I included, which is the .Net source code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM