Question

Je souhaite effectuer une copie complète d'un objet 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 une chaîne XML, puis le reparse, mais je me demande s'il existe un meilleur moyen.

Était-ce utile?

La solution

Il n’est pas nécessaire 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);
}

Autres conseils

Il semble que la meilleure méthode consiste à utiliser la méthode ToString and reparse. Voici le code:

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

Levé directement à partir de C # 3.0 en bref :

Lorsqu'un noeud ou un attribut est ajouté à un élément (via une construction fonctionnelle ou une méthode Add), la propriété Parent du noeud ou de l'attribut est définie sur cet élément. Un nœud ne peut avoir qu'un seul élément parent: si vous ajoutez un nœud déjà parent à un second parent, le nœud est automatiquement cloné en profondeur. Dans l'exemple suivant, chaque client dispose d'une copie d'adresse distincte:

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 automatique préserve l’instanciation d’objets X-DOM sans effets secondaires, ce qui est une autre caractéristique de la programmation fonctionnelle.

Cela devrait fonctionner:

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

Je ne pense pas qu'il existe un mécanisme permettant de réaliser 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 de nouveau dans un arbre
  2. Ecrivez sur vous avec un motif visiteur

Le nombre de visiteurs est certes possible, mais il faudra beaucoup de travail et d’essais. Je pense que votre meilleure option est la première.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top