Partager via


Modification de l’arborescence XML en mémoire et construction fonctionnelle (LINQ to XML)

La modification d’une arborescence XML en place est une approche traditionnelle de la modification de la forme d’un document XML. Une application classique charge un document dans un magasin de données tel que DOM ou LINQ to XML ; utilise une interface de programmation pour insérer ou supprimer des nœuds, ou modifier leur contenu ; puis enregistre le code XML dans un fichier ou le transmet sur un réseau.

LINQ to XML permet une autre approche utile dans de nombreux scénarios : construction fonctionnelle. La construction fonctionnelle traite la modification des données comme un problème de transformation, plutôt que comme une manipulation détaillée d’un magasin de données. Si vous pouvez prendre une représentation des données et le transformer efficacement d’un formulaire à un autre, le résultat est le même que si vous avez pris un magasin de données et l’avez manipulé d’une manière quelconque pour prendre une autre forme. Une clé de l’approche de construction fonctionnelle consiste à transmettre les résultats des requêtes aux constructeurs XDocument et XElement.

Dans de nombreux cas, vous pouvez écrire le code transformationnel dans une fraction du temps nécessaire pour manipuler le magasin de données, et le code résultant est plus robuste et plus facile à gérer. Dans ces cas, même si l’approche transformationnelle peut prendre plus de puissance de traitement, il s’agit d’un moyen plus efficace de modifier les données. Si un développeur est familiarisé avec l’approche fonctionnelle, le code résultant dans de nombreux cas est plus facile à comprendre et il est facile de trouver le code qui modifie chaque partie de l’arborescence.

L’approche dans laquelle vous modifiez une arborescence XML en place est plus familière à de nombreux programmeurs DOM, tandis que le code écrit à l’aide de l’approche fonctionnelle peut sembler inconnu pour un développeur qui ne comprend pas encore cette approche. Si vous devez uniquement apporter une petite modification à une arborescence XML volumineuse, l’approche dans laquelle vous modifiez une arborescence en place dans de nombreux cas prendra moins de temps processeur.

Cet article fournit des exemples des deux approches. Supposons que vous souhaitez modifier le document XML simple suivant afin que les attributs deviennent des éléments :

<?xml version="1.0" encoding="utf-8" ?>
<Root Data1="123" Data2="456">
  <Child1>Content</Child1>
</Root>

La première des exemples suivants utilise l’approche traditionnelle de modification sur place, et la seconde utilise l’approche de construction fonctionnelle.

Exemple : transformer des attributs en éléments avec l’approche traditionnelle sur place

Vous pouvez écrire du code procédural pour créer des éléments à partir des attributs, puis supprimer les attributs, comme suit :

XElement root = XElement.Load("Data.xml");
foreach (XAttribute att in root.Attributes()) {
    root.Add(new XElement(att.Name, (string)att));
}
root.Attributes().Remove();
Console.WriteLine(root);
Dim root As XElement = XElement.Load("Data.xml")
For Each att As XAttribute In root.Attributes()
    root.Add(New XElement(att.Name, att.Value))
Next
root.Attributes().Remove()
Console.WriteLine(root)

Cet exemple génère la sortie suivante :

<Root>
  <Child1>Content</Child1>
  <Data1>123</Data1>
  <Data2>456</Data2>
</Root>

Exemple : transformer des attributs en éléments avec l’approche de construction fonctionnelle

En revanche, une approche fonctionnelle se compose de code pour former une nouvelle arborescence, choisir et choisir des éléments et des attributs à partir de l’arborescence source, et les transformer selon les besoins à mesure qu’ils sont ajoutés à la nouvelle arborescence.

XElement root = XElement.Load("Data.xml");
XElement newTree = new XElement("Root",
    root.Element("Child1"),
    from att in root.Attributes()
    select new XElement(att.Name, (string)att)
);
Console.WriteLine(newTree);
Dim root As XElement = XElement.Load("Data.xml")
Dim newTree As XElement = _
    <Root>
        <%= root.<Child1> %>
        <%= From att In root.Attributes() _
            Select New XElement(att.Name, att.Value) %>
    </Root>
Console.WriteLine(newTree)

Cet exemple génère le même code XML que le premier exemple. Toutefois, notez que vous pouvez réellement voir la structure résultante du nouveau XML dans l’approche fonctionnelle. Vous pouvez voir la création de l’élément Root , le code qui extrait l’élément Child1 de l’arborescence source et le code qui transforme les attributs de l’arborescence source en éléments de la nouvelle arborescence.

L’exemple fonctionnel dans ce cas n’est ni plus court ni plus simple que le premier exemple. Toutefois, si vous avez de nombreuses modifications à apporter à une arborescence XML, l’approche procédurale devient assez complexe et quelque peu obtuse. En revanche, lorsque vous utilisez l’approche fonctionnelle, vous créez toujours simplement le code XML souhaité, en incorporant des requêtes et des expressions selon les besoins, pour extraire le contenu souhaité. L’approche fonctionnelle génère du code plus facile à gérer.

Notez que dans ce cas, l’approche fonctionnelle ne serait probablement pas aussi performante que l’approche de manipulation d’arborescence. Le principal problème est que l’approche fonctionnelle génère davantage d'objets de courte durée. Toutefois, le compromis est efficace si l’utilisation de l’approche fonctionnelle permet une plus grande productivité du programmeur.

Il s’agit d’un exemple très simple, mais il sert à montrer la différence de philosophie entre les deux approches. L’approche fonctionnelle génère des gains de productivité accrus pour transformer des documents XML plus volumineux.