如何在LINQ to XML中对元素进行深层复制?

Dan*_*ted 62 .net linq-to-xml

我想制作一个LINQ to XML XElement的深层副本.我想这样做的原因是文档中有一些节点我想创建(在同一文档中)的修改副本.我没有看到这样做的方法.

我可以将元素转换为XML字符串然后重新解析它,但我想知道是否有更好的方法.

Jon*_*att 119

没有必要重新解析.XElement的构造函数之一采用另一个XElement并对其进行深层复制:

XElement original = new XElement("original");
XElement deepCopy = new XElement(original);
Run Code Online (Sandbox Code Playgroud)

这里有几个单元测试来演示:

[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);
}
Run Code Online (Sandbox Code Playgroud)

  • 我相信这个例子中使用的构造函数通常称为**复制构造函数**.这是[`XElement` Copy Constructor]的文档(http://msdn.microsoft.com/en-us/library/bb297950%28v=vs.110%29.aspx).还有一个[`XDocument` Copy Constructor](http://msdn.microsoft.com/en-us/library/bb341301%28v=vs.110%29.aspx).对我们来说幸运的是,**LINQ to XML**使这很容易...... [深度复制(或克隆)](http://stackoverflow.com/questions/78536/deep-cloning-objects-in-c -sharp)可以多次不那么直截了当. (4认同)
  • 虽然有点晚了,但第一个测试用例与浅复制无关。这根本不是副本,它是对同一对象的第二次引用。您可以将相同的原则应用于 C# 中的所有非基本类型。 (3认同)

Dan*_*ted 8

看起来像ToString和重新分析方法是最好的方法.这是代码:

XElement copy = XElement.Parse(original.ToString());
Run Code Online (Sandbox Code Playgroud)


Won*_*nko 5

简而言之,直接从 C# 3.0 提升:

\n\n

当将节点或属性添加到元素时(无论是通过函数构造还是 Add 方法),节点或属性的 Parent 属性将设置为该元素。一个节点只能有一个父元素:如果将一个已成为父节点的节点添加到第二个父节点,该节点将自动深度克隆。在以下示例中,每个客户都有一个单独的地址副本:

\n\n
var address = new XElement ("address",\n                  new XElement ("street", "Lawley St"),\n                  new XElement ("town", "North Beach")\n              );\nvar customer1 = new XElement ("customer1", address);\nvar customer2 = new XElement ("customer2", address);\n\ncustomer1.Element ("address").Element ("street").Value = "Another St";\nConsole.WriteLine (\n  customer2.Element ("address").Element ("street").Value);   // Lawley St\n
Run Code Online (Sandbox Code Playgroud)\n\n

这种自动复制使 X-DOM 对象实例化没有副作用\xe2\x80\x94另一个函数式编程的标志。

\n