【问题标题】:Deep Copy of XDocument/Element with associated XElement (s)XDocument/Element 的深层副本与关联的 XElement (s)
【发布时间】:2014-07-28 13:02:08
【问题描述】:

好的,我有一个 XDocument

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

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

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

我想对两者进行深拷贝,

有没有比,更有效的方法,

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

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

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

当前解决方案:

我想要解决方案:

【问题讨论】:

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


    【解决方案1】:

    就您制作的 XDocument 副本而言,我们知道它肯定会尽可能快,as we can see from the documentation at line 2320。这会按照我们想要的方式进行深层复制。

    如果您需要对 XDocument 对象进行深层复制,那么就性能而言,上述方法是最好的方法。它对文档中的每个节点(包括 XElements、XAttributes、cmets 等)执行深层复制,而无需重新加载文件。它在内存中读取并克隆所有节点。这是一个高效的操作,也是我们可以拥有的最高效的操作,因为它会自动抑制通常在 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 的两次调用输出不同的值,表明这两个引用指向具有不同结构的不同项,证明进行了深层复制。

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

    【讨论】:

    • 非常感谢您的回答! XDocument 副本没有问题。似乎我的问题不清楚。我会更新的!
    • 你好@cellz。如果您按照我的回答中包含的链接进行操作,您会注意到 XDocument deepCopy = new XDocument(BaseDocument);是您可以拥有的最佳解决方案:它是深层副本,并且是手动创建新 XDocument 的最快方法。
    • 但我的问题不在于单个 XDocument 的副本。 XDocument deepCopy = new XDocument(oldDocumentReference);这当然是这部分的最佳解决方案,我不想质疑这一点。对不起!
    • 对不起,我刚刚了解您的问题。
    • 一会儿我会修改我的答案。
    猜你喜欢
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 2012-05-16
    • 2016-01-29
    • 1970-01-01
    相关资源
    最近更新 更多