2008-10-16 13 views
49

XML XElement için bir LINQ dosyasının derin bir kopyasını yapmak istiyorum. Bunu yapmak istediğim nedeni, belgede (aynı belgede) değiştirilmiş kopyalar oluşturmak istediğim bazı düğümler var. Bunu yapmak için bir yöntem görmüyorum.LINQ'daki bir öğenin derin kopyasını XML'ye nasıl yapabilirim?

Öğeyi bir XML dizesine dönüştürebilir ve sonra yeniden inceleyebilirim, ancak daha iyi bir yol olup olmadığını merak ediyorum.

+0

Daniel - Bence bu soruya verilen cevabı tekrar gözden geçirmelisiniz. –

+0

Bitti - Kabul edilen cevabı değiştirdim. –

cevap

98

Yeniden dağıtmaya gerek yoktur. XElement yapıcıları biri başka XElement alır ve ona derin bir kopyasını oluşturur:

[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); 
} 
+0

+1: * Bu * gönderi kabul edilen cevap olmalıdır. Test yöntemleri için –

+0

+1. –

+2

Bu örnekte kullanılan yapıcının jenerik olarak ** Kopyalama Yapıcı ** olarak bilindiğine inanıyorum. İşte ['XElement' Kopya Oluşturucu] için belge (http://msdn.microsoft.com/en-us/library/bb297950%28v=vs.110%29.aspx). Ayrıca bir [XDocument 'Kopya Oluşturucu] (http://msdn.microsoft.com/en-us/library/bb341301%28v=vs.110%29.aspx) de bulunmaktadır. Neyse ki bizim için, ** LINQ to XML ** bunu kolaylaştırır ... genel olarak, [Derin Kopyalama (veya Klonlama)] (http://stackoverflow.com/questions/78536/deep-cloning-objects-in-c -sharp) birçok kez bu kadar basit olamaz. – DavidRR

-2

XNode stil ağacının derin bir kopyasını gerçekleştirmenize izin veren mevcut bir mekanizmanın olduğuna inanmıyorum. Sanırım iki seçeneğiniz kaldı. Eğer bir dizeye bir dönüştürmek önerildiği gibi

  1. yapın ve sonra tekrar bir ağaca
  2. yaz kendin için bir ziyaretçinin desen

ziyaretçi desen kesinlikle mümkün olan ama iyi bir anlaşma alacak iş bir test. Bence en iyi seçeneğin # 1.

6

ToString ve yeniden işleme yönteminin en iyi yol olduğu anlaşılıyor.

XElement copy = XElement.Parse(original.ToString()); 
+0

sonra DstNode.Add (kopya) eklemek için. Bitti. – Fraga

2

C# 3.0 in a Nutshell şirketinden Artırılan:

bir düğüm veya nitelik düğüm veya özelliğin üst özelliği olarak ayarlanır (işlevsel yapı veya Add yöntemi ile olsun) bir elemana ilave edilir Burada kod bu eleman. Düğüm yalnızca bir ana öğeye sahip olabilir: ikinci bir ebeveyne zaten atanmış bir düğüm eklerseniz, düğüm otomatik olarak derin klonlanır.

var address = new XElement ("address", 
        new XElement ("street", "Lawley St"), 
        new XElement ("town", "North Beach") 
      ); 
var customer1 = new XElement ("customer1", address); 
var customer2 = new XElement ("customer2", address); 

customer1.Element ("address").Element ("street").Value = "Another St"; 
Console.WriteLine (
    customer2.Element ("address").Element ("street").Value); // Lawley St 

Bu otomatik çoğaltılması yan etkileri-başka fonksiyonel programlamanın damgasını ücretsiz X-DOM nesne örneğini tutar: Aşağıdaki örnekte, her bir müşteri adresinin ayrı bir kopyası vardır.

+3

Bu neden kabul edilen cevap olarak işaretlendi? –

0

Bu çalışması gerekir:

var copy = new XElement(original.Name, original.Attributes(), 
         original.Elements()); 
İşte
XElement original = new XElement("original"); 
XElement deepCopy = new XElement(original); 

birim testlerin bir çift göstermek için vardır
İlgili konular