简体   繁体   English

具有关联的XElement的XDocument / Element的深层复制

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

Ok I have a XDocument 好的,我有一个XDocument

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

and some DataStructure of XElements (inside the XDocument) that gets generated by a method. 以及通过方法生成的XElement的一些DataStructure(在XDocument内部)。 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? 复制数据结构,以便内部的XElements引用新副本?

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 . 就您制作的XDocument副本而言,我们可以肯定的是, 正如我们从第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. 如果您需要对XDocument对象进行深层复制,那么以上是关于性能的最佳方法。 It performs a deep copy of every node in the document (including XElements, XAttributes, comments etc.) without having to reload the file. 它无需重新加载文件即可对文档中的每个节点(包括XElement,XAttributes,注释等)执行深层复制。 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. 这是一种高效的操作,也是我们所能获得的最高效的操作,因为它会自动禁止通常在XDocument内部触发的所有通知事件。 The deep copy can be verified from the below: 可以从以下方式验证深层副本:

XML used: 使用的XML:

<?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. 对Console.WriteLine的两次调用输出不同的值,指示两个引用指向具有不同结构的不同项,从而证明已进行了深拷贝。

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. 请注意,如果要重复使用现有的XElement,则无法在不使用反射的情况下将它们设置到XDocument中:在XDocument中设置XElement的所有公共方法都将执行深层复制。 This is evident from the link I included, which is the .Net source code. 从我包含的链接(.Net源代码)可以明显看出这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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