Ich möchte eine tiefe Kopie eines LINQ to XML XElement erstellen. Der Grund, warum ich dies tun möchte, ist, dass das Dokument einige Knoten enthält, von denen ich geänderte Kopien erstellen möchte (im selben Dokument). Ich sehe keine Methode, um dies zu tun.
Ich könnte das Element in eine XML-Zeichenfolge konvertieren und dann erneut analysieren, aber ich frage mich, ob es einen besseren Weg gibt.
.net
linq-to-xml
Daniel Plaisted
quelle
quelle
Antworten:
Es besteht keine Notwendigkeit zu reparieren. Einer der Konstruktoren von XElement nimmt ein anderes XElement und erstellt eine tiefe Kopie davon:
XElement original = new XElement("original"); XElement deepCopy = new XElement(original);
Hier sind einige Unit-Tests, um zu demonstrieren:
[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); }
quelle
XElement
Kopierkonstruktor . Es gibt auch einenXDocument
Kopierkonstruktor . Zum Glück macht LINQ to XML dies einfach ... Im Allgemeinen kann Deep Copying (oder Klonen) oft nicht so einfach sein.DeepEquals
damit wird gezeigt, dass die beiden Knoten jetzt unterschiedlich sind.Es sieht so aus, als ob die ToString- und Resese-Methode der beste Weg ist. Hier ist der Code:
XElement copy = XElement.Parse(original.ToString());
quelle
Direkt von C # 3.0 auf den Punkt gebracht :
Wenn einem Element ein Knoten oder Attribut hinzugefügt wird (ob über eine Funktionskonstruktion oder eine Add-Methode), wird die Parent-Eigenschaft des Knotens oder Attributs auf dieses Element festgelegt. Ein Knoten kann nur ein übergeordnetes Element haben: Wenn Sie einem zweiten übergeordneten Knoten einen bereits übergeordneten Knoten hinzufügen, wird der Knoten automatisch tief geklont. Im folgenden Beispiel hat jeder Kunde eine separate Kopie der Adresse:
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
Diese automatische Vervielfältigung hält die Instanziierung von X-DOM-Objekten frei von Nebenwirkungen - ein weiteres Kennzeichen der funktionalen Programmierung.
quelle
Das sollte funktionieren:
var copy = new XElement(original.Name, original.Attributes(), original.Elements() );
quelle
new XElement(original)
. Eine bessere Möglichkeit ist die Verwendung des Kopierkonstruktors .Ich glaube nicht, dass es einen Mechanismus gibt, mit dem Sie eine tiefe Kopie eines XNode-Baums erstellen können. Ich denke, Sie haben zwei Möglichkeiten.
Das Besuchermuster ist sicherlich möglich, aber es wird viel Arbeit und Tests erfordern. Ich denke, Ihre beste Option ist # 1.
quelle