具有关联XElement的XDocument / Element的深层副本

时间:2014-07-28 13:02:09

标签: c# linq-to-xml deep-copy

好的,我有一个XDocument

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

以及由方法生成的XElements的一些DataStructure(在XDocument中)。这只是一个例子:

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

我想对两者进行深度复制,

是否有比

更有效的方法
XDocument copy = new XDocument(BaseDocument);
Dictionary<string, List<XElement>> copyElementMap = GetElementMapping(copy);

复制数据结构,以便内部的XElements引用新副本?

我做了一些照片来展示我想要的东西:

当前解决方案: Copy & Regeneration

我想解决方案: Copy All

1 个答案:

答案 0 :(得分:2)

就你所制作的XDocument副本而言,我们知道它确实是最快的,as we can see from the documentation at line 2320。这会按照我们希望的方式进行深层复制。

如果您需要对XDocument对象进行深层复制,那么以上是关于性能的最佳方法。它执行文档中每个节点的深层复制(包括XElements,XAttributes,注释等),而无需重新加载文件。它在内存中读取和克隆所有节点。这是一个高效的操作,它是我们可以拥有的最高效的,因为它会自动抑制通常在XDocument内部触发的所有通知事件。深层副本可以从下面验证:

使用的XML:

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

源代码

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();

对Console.WriteLine的两次调用输出不同的值,表明这两个引用指向具有不同结构的不同项,证明已进行深层复制。

请注意,如果要重新使用所拥有的XElements,则无法在不使用反射的情况下将它们设置为XDocument:在XDocument中设置XElements的所有公共方法都执行深层复制。从我所包含的链接中可以看出这一点,即.Net源代码。