La classe XElement manipulations de document XML en Csharp

Découvrez comment manipuler rapidement des documents XML à l'aide des objets XElement,XAttribute,XCadata et Linq en Csharp (c#). Cas pratiques avec des exemples.

  Publié le

Qu'est-ce que l'objet XElement ?

En Csharp, la classe XElement est l'un des objets fondamentaux nécessaires pour manipuler efficacement le XML. Elle sert à représenter un noeud XML, en concevant l'ensemble de son arborescence (attributs, contenus du nœud, descendant,etc.). L'objet XElement peut également interagir avec d'autres classes propres à l'espace de nom System.Xml (XmlReader,XmlWriter,etc).

Qu'elles sont les fonctions de l'objet XElement ?

La classe XElement permet de créer des éléments, d'ajouter ou de modifier le contenu d'un nœud XML. D'ajouter, de modifier ou de supprimer ses descendants, ainsi que ses attributs. L'objet XElement offre également la possibilité de sérialiser le conteur d'un élément sous forme d'une chaine de caractère.

Comment créer un objet XElement ?

L'initialisation de l'objet XElement permet de créer un XML simplement.

XElement xet = new XElement("root");

Le résultat de cette générera le XML suivant :

<root>
</root>

Il est parfaitement possible de cumuler et d'imbriquer les initialisations d'objets XElement,XAttribute et XCdata.La règle est simple, un XElement peut contenir d'autres XElement,un ou plusieurs XAttribute, et un seul XCdata.

xet = new XElement("root", 
	new XElement("parent",
	   new XAttribute("level", "0"),
	   new XElement("child",
		   new XAttribute("id", "1"),
		   new XAttribute("level", "1"),
		   new XElement("sub_child",
			   new XAttribute("level", "1")
	   )),

		  new XElement("child",
		   new XAttribute("id", "2"),
		   new XAttribute("level", "1"),
		   new XElement("sub_child",
			   new XAttribute("level", "1")
	   ))));

Ce qui correspondra à l'architecture XML suivante :

<root>
  <parent level="0">
    <child id="1" level="1">
      <sub_child level="1" />
    </child>
    <child id="2" level="1">
      <sub_child level="1" />
    </child>
  </parent>
</root>

Comment convertir une chaine de caractères en objet XElement ?

Il est possible de convertir facilement une chaine de caractères en entité XElement, en utilisant la méthode XElement.Parse. Attention cependant la chaine de caractères doit répondre aux critères d'un XML et donc être correctement formatée.

XElement xet = XElement.Parse("<root></root>");

Comment sauvegarder un objet XElement en fichier XML ?

L'objet XElement inclut une méthode save qui sert à sauvegarder n'importe quel objet XElement dans un fichier XML spécifié. Si le fichier existe déjà cette méthode remplace le fichier existant par le nouveau contenu XML.

XElement xet = new XElement("root");
xet.Save("output.xml");

Comment charger un objet XElement depuis fichier XML ?

La classe XElement comporte une fonction load permettant de charger n'importe quel fichier XML et de le convertir en XElement exploitable.

XElement xet = XElement.Load("input.xml");

Comment manipuler rapidement les données d'un XElement ?

La classe XElement intègre l'interface IEnumerable lui permettant de servir de source de données pour utiliser les requêtes LINQ. Il est donc très aisé de filtrer et trier ses éléments grâce aux méthodes proposées par LINQ. Pour la suite de ces explications nous utiliserons le modèle XML suivant et considérerons qu'il sera contenu dans la variable xet sous la forme d'un XElement :

<root>
  <parent level="0">
    <child id="1" level="1">
      <sub_child level="1" />
    </child>
    <child id="2" level="1">
      <sub_child level="1" />
    </child>
  </parent>
</root>

Comment séléctionner un noeud par son nom dans la liste des descendants du noeud racine ?

Pour séléctionner le noeud parent descendant du noeud root :

XElement parent = xet.Descendants("parent").First();

Pour séléctionner le premier noeud child descendant du noeud root :

XElement parent = xet.Descendants("child").First();

Comment séléctionner un noeud par la valeur d'un attribut ?

Pour séléctionner le noeud child avec l'attribut id de valeur 2 :

XElement child_2 = xet.Descendants("child").Where(x => x.Attribute("id").Value == "2").First();

Comment séléctionner un noeud par la valeur de plusieurs attributs ?

Pour séléctionner le noeud child avec l'attribut level de valeur 1 et  avec l'attribut id de valeur 2 :

XElement child_2 = xet.Descendants("child").Where(x => x.Attribute("level").Value == "1" && x.Attribute("id").Value == "2").First();

Comment séléctionner un  groupe de noeuds par la valeur d'un attribut ?

Pour séléctionner l'ensemble des noeuds child avec l'attribut level de valeur 1 :

var list_childs = xet.Descendants("child").Where(x => x.Attribute("id").Value == "2");

Comment séléctionner l'attribut d'un noeud par la valeur d'un attribut sur le noeud ?

Pour récupérer la référence mémoire de l'attribut id du premier noeud child avec l'attribut level de valeur 1 :

XAttribute attr_level_child = xet.Descendants("child").Where(x => x.Attribute("level").Value == "1").First().Attribute("id");

Comment changer rapidement la valeur d'un attribut d'un XElement ?

L'objet XAttribute bénéficie de la propriété value et l'objet XElement de la méthode SetAttributeValue qui sert à modifier rapidement la valeur d'un XAttribute. Dans le second cas l'usage de SetAttributeValue, si l'attribut n'éxiste pas il est automatiquement rajouté.

XAttribute attr_level_child = xet.Descendants("child").Where(x => x.Attribute("level").Value == "1").First().Attribute("id");
attr_level_child.Value = "5";

//OU 

XElement child = xet.Descendants("child").Where(x => x.Attribute("level").Value == "1").First();
child.SetAttributeValue("level","5"); 
<root>
  <parent level="0">
    <child id="1" level="5">
      <sub_child level="1" />
    </child>
    <child id="2" level="1">
      <sub_child level="1" />
    </child>
  </parent>
</root>

Comment changer rapidement un noeud XElement ?

Avec le XElement, il est possible de modifier directement le contenu immédiat d'un noeud grâce à la méthode SetValue.

XElement child = xet.Descendants("child").Where(x => x.Attribute("level").Value == "1").First();
child_2.ReplaceAll(new XAttribute("demo", "15"), new XCData("mon nouveau contenu 2"));
<root>
  <parent level="0">
    <child id="1" level="1">
      <sub_child level="1" />
    </child>
    <child demo="15"><![CDATA[mon nouveau contenu 2]]></child>
  </parent>
</root>

Comment supprimer un nœud XML descendant d'un objet XElement ?

Il est parfaitement possible de supprimer un ou plusieurs nœuds XML précédemment sélectionnés grâce à une requête LINQ, à l'aide de la fonction remove.

xet.Descendants("child").Where(x => x.Attribute("level").Value == "1").First().Remove();
<root>
  <parent level="0">
    <child id="2" level="1">
      <sub_child level="1" />
    </child>
  </parent>
</root>

Comment supprimer plusieurs noeuds XML descendant d'un objet XElement ?

La encore la fonction remove permet de supprimer l'ensemble des noeuds XML présent dans la collection retournée par le filtre LINQ.

xet.Descendants("child").Where(x => x.Attribute("level").Value == "1").Remove();