66 votes

Comment puis-je copier en profondeur un élément de LINQ to XML?

Je souhaite créer une copie complète d’un fichier LINQ to XML XElement. La raison pour laquelle je veux faire cela est qu'il y a quelques nœuds dans le document pour lesquels je veux créer des copies modifiées (dans le même document). Je ne vois pas de méthode pour le faire.

Je pourrais convertir l’élément en chaîne XML, puis l’analyser, mais je me demande s’il existe un meilleur moyen.

125voto

Jonathan Moffatt Points 4322

Il n'y a pas besoin de réparer. L'un des constructeurs de XElement prend un autre XElement et en fait une copie complète:

 XElement original = new XElement("original");
XElement deepCopy = new XElement(original);
 

Voici quelques tests unitaires à démontrer:

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

9voto

Daniel Plaisted Points 11183

Il semble que la méthode ToString and reparse soit la meilleure solution. Voici le code:

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

3voto

Wonko Points 1248

Levées directement à partir de C# 3.0, en un Mot:

Lorsqu'un nœud ou d'un attribut est ajouté à un élément (que ce soit par la construction fonctionnelle ou une méthode Add) le nœud ou l'attribut Parent de la propriété est définie à cet élément. Un nœud peut avoir qu'un seul élément parent: si vous ajoutez un à déjà eu un nœud à un autre parent, le nœud est automatiquement profonde cloné. Dans l'exemple suivant, chaque client dispose d'une copie distincte de l'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

Cette duplication maintient X-DOM l'instanciation d'objets sans effets secondaires-une autre caractéristique de la programmation fonctionnelle.

0voto

Chris Cavanagh Points 1

Cela devrait fonctionner:

 var copy = new XElement(original.Name, original.Attributes(),
                        original.Elements() );
 

-2voto

JaredPar Points 333733

Je ne pense pas qu’il existe un mécanisme permettant d’effectuer une copie complète d’une arborescence de styles XNode. Je pense qu'il vous reste deux options.

  1. Faites ce que vous avez suggéré de convertir en chaîne puis en arbre.
  2. Écrivez sur vous-même avec un motif visiteur

La fréquentation est certes possible, mais il faudra beaucoup de travail et d’essais. Je pense que votre meilleure option est n ° 1.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X