Les articles de ESSI# - La sérialisation XML sous .NET facile

RACINE

La sérialisation XML sous .NET facile

Index Rapide

Introduction

XML et .NET : une grande histoire d'amour annoncée par Microsoft. Alors, le couple est-il heureux ? L'union est-elle consommée ?

Comment, nous, "simples programmeurs" pouvons profiter de l'intégration de cette technologie (et des technologies périphériques : XPath, XSD, etc ...) facilement ?
Je vais tâcher de présenter de manière simple un point précis : comment se faciliter la sérialisation XML ?


Pour utiliser .NET framework, vous devez avoir installé sur votre poste AU MOINS :
  1. Windows XP Pro ou 2000 avec SP2 ou NT4 avec SP6a
  2. Internet Explorer 5.01
  3. IIS (mais pas dans tout les cas)
  4. .NET Framework SDK (evidemment !!)
  5. un éditeur de votre choix (emacs ou VS.NET suivant les courants de pensée et les moyens)

Je prends pour pré-requis que mon lecteur a un niveau même faible en C# (voir de Java au vues de ressemblances syntaxiques), mais a quand même les bases en ce qui concerne XML (XSD serait un plus).

Pour que vous puissiez bien faire ce TP, si vous n'êtes pas familier avec .NET ou XML, prenez le temps de regarder la présentation faite à l'ESSI en HTML ou PPT.

Une première partie de ce code a déjà été présenté (notamment la validation XML par XSD) dans le TP Outils GL : XML dans .NET. Jetez y un oeil !

Voici la liste des différents styles visuels utilisés dans ce cours (et les suivants) :
Si vous voyez ceci ... ...ça veut dire cela.
IDisposable Interface C'est un lien vers une page d'aide du .NET Framework SDK. Ce lien ne fonctionnera que si le .NET framework SDK ANGLAIS est installé sur votre poste courant.
Si vous avez la version française, modifiez les liens comme suit :
ms-help://MS.NETFrameworkSDK/... en
ms-help://MS.NETFrameworkSDK.Fr/...

Ok, c'est pas forcément une bonne idée de Microsoft, mais c'est ainsi ... :(
--> téléchargez le source
C'est un lien vers un fichier téléchargeable hosté sur le même site.

retour à l'index

Sérialisation XML simplifiée

Cliquez pour télécharger Cliquez ici pour obtenir le .NET Framework SDK (130 Mo).

Xml Schema Description (XSD)

Si vous ne connaissez pas XSD, jetez un oeil sur ce tutoriel chez W3Schools.com et à l'article sur le TP Outils GL : XML dans .NET.

C'est le plus simple ! Si vous avez un document XSD bien formé, décrivant les données que vous cherchez à sérialiser alors .NET va faire la plus grosse partie du boulot pour vous.

1/ Validez

Valider un document XML à partir de fichiers XSD est simplissime sous .NET !!! Tout est expliqué dans le TP Outils GL : XML dans .NET.
Cela se fait en moins de 10 lignes, et est complètement automatisé. Regardez, ça vaut le coup d'oeil ...

2/ Extraire les classes

Cela se fait à l'aide de l'outil nommé xsd.exe qui peut (entre autre) générer un ensemble de classes C# (ou autre langage .NET) qui correspondent à celles présentes dans votre fichier XSD : ce sont les complexType et les element "à la racine".

Comment l'utiliser ?
> xsd.exe /classes /l:CS monschema.xsd
Le fichier produit se nommera monschema.cs (dans notre exemple).

Attention ! Si vous avez un schéma valide et 100% fonctionnel mais qu'il est recursif, alors il y a des chances que xsd.exe refuse votre schéma. Et pour le fun, il lève une belle exception prétextant un "Stack overflow" ! Si vous êtes malheureusement dans ce cas (et cela m'est arrivé) sautez au chapitre Sérialisation XML avancée.

Si tout se passe comme prévu, vous devriez avoir dans votre fichier .cs une (ou plusieurs) classes qui contiennent comme attributs publiques les attributs de la classe ainsi que ses sous éléments. Vous remarquerez aussi plein d'attributs de méthodes indiquant la manière de sérialiser les attributs de la classe (voir préciser un type). En effet, ces derniers peuvent être sérialisés sous forme d'attributs ou sous forme de sous éléments.
Ces attributs sont décrits dans la section ci-dessous Attributs de sérialisation.

retour à l'index

Déserialisation

Et maintenant, vous possédez toutes les classes qui sont présentes dans votre fichier XSD. Il ne vous reste plus qu'à déserialiser votre flux XML en une sympathique arborescence.

Voici comment faire en quelques lignes :
1:  XmlSerializer serializer = new XmlSerializer(typeof(LeTypeRacine));
2:
3:  TextReader reader = new StreamReader("unfichierXML.xml");
4:  LeTypeRacine root = (LeTypeRacine)serializer.Deserialize(reader);
5:
6:  reader.Close();
#Ligne
Explication
1 Il faut créer un objet qui puisse sérialiser et déserialiser votre arborescence de classes. La chose interressante à remarquer est que vous passez un Type en paramètre du constructeur du sérialiseur. Grâce à cela, et aux attributs de sérialisation qui ont été générés par xsd.exe, le sérialisateur sera à même de manipuler ces classes et de reconstruire l'arbre contenu dans le flux XML très facilement.

Pour l'exemple, le type de base attendu dans le flot XML est LeTypeRacine.
3 Création d'un reader sur le fichier XML contenant les données à déserialiser.
4 En une ligne, le contenu entier du fichier XML est déserialisé en un objet correspondant à l'élément racine du fichier XML.
6 On ferme le reader, c'est mieux.

Maintenant, vous avez un élément (généralement assimilé à une arborescence) qui contient les donnée contenues dans votre fichier XML. A vous de l'utiliser comme bon vous semble ...

retour à l'index

Sérialisation

C'est la procédure similaire à celle-ci dessus, donc voici un exemple de codage. On suppose que vous voulez sérialiser un objet de type LeTypeRacine de nom root.
1:  XmlSerializer serializer = new XmlSerializer(typeof(LeTypeRacine));
2:
3:  TextWriter writer = new StreamWriter("unfichierXML.xml");
4:  serializer.Deserialize(writer, root);
5:
6:  writer.Close();

retour à l'index

Sérialisation XML avancée

Pourquoi se donner de la peine ?

Attributs de sérialisation

Puisque xsd.exe refuse de faire le boulot pour vous, vous allez devoir mettre les mains dans le cambouis. Comment ? Ceci revient à répondre à la question "que fait xsd.exe ?".

Tout d'abord, une seule clause using est nécessaire : using System.Xml.Serialization;

Ensuite, il faut préciser à .NET (plus précisément au XmlSerializer) comment sérialiser les attributs publics de la classe (les seuls qui seront sérialisés).
Sachez que par défaut, les attributs sont sérialisés comme des sous-éléments. Si vous désirez que les attributs soient sérialisés comme des attributs (sic) du noeud XML, il faut préciser l'attribut [XmlAttributeAttribute()]. Par exemple :
public class LaClasse{

  [XmlAttributeAttribute()]
  public string unattribut;
}
	

Attributes that Control XML Serialization contient la liste de tout les attributs contrôlant la sérialisation XML.

Voici un tableau récapitulatif (et non exhaustif) des attributs courants :
Nom Explication S'applique sur
XmlAttributeAttribute L'attribut doit être sérialisé comme un attribut du noeud XML. Ainsi le code suivant :
public class LaClasse{
  [XmlAttributeAttribute(DataType="string")]
  public string unattribut;
}
... produit l'XML suivant ...
<LaClasse unattribut="une valeur string" />
Remarquez la propriété DataType = "string" qui indique comment écrire la valeur de l'attribut. Sachez qu'énormément de types sont disponibles (date, byte, duration, etc...). Regardez la doc de XmlAttributeAttribute.DataType.

Sachez enfin que si vous précisez la propriété AttributName= "unAutreNom", l'attribut portera le nom unAutreNom dans le fichier XML.
attribut
XmlIgnoreAttribute L'attribut doit être ignoré et ne pas être sérialisé. Ainsi le code suivant :
public class LaClasse{
  [XmlIgnoreAttribute()]
  public string unattribut;
}
... produit l'XML suivant ...
<LaClasse />
attribut
XmlElementAttribute L'attribut doit être sérialisé comme un sous-élément. Ainsi le code suivant :
public class LaClasse{
  [XmlElementAttribute()]
  public string unattribut;
}
... produit l'XML suivant ...
<LaClasse>
  <unattribut>un string ...</unattribut>
</LaClasse>
Vous pouvez comme avec XmlAttributeAttribute préciser un type, un nom, etc ... pour l'élément.
attribut
XmlRootAttribute La classe représente le type de l'élément racine du document XML. En exemple, le code suivant :
[XmlRootAttribute()]
public class LaClasse{
  public string unattribut;
}
Vous pouvez comme avec XmlAttributeAttribute préciser un nom, etc ... pour l'élément. Vous pouvez préciser s'il est obligatoire, un namespace, etc...
classe

Avec ces 4 attributs vous devriez pouvoir couvrir une grosse partie des besoins d'un document XML simple. Pour une liste complète : Attributes that Control XML Serialization dans l'aide .NET.

retour à l'index

Un exemple

Cliquez pour télécharger Cliquez ici pour obtenir le source et l'EXE du programme.

Encore une fois, rien ne vaut mieux qu'un exemple pour comprendre !

Dans cet exemple, je modélise une Personne ayant certains attributs sérialisés (nom, age) et certains non sérialisés (numsécu). Un Personne possède aussi au tableau de Voiture (une classe ayant comme simple attribut un numéro de plaque).

L'idée est simple : on créé une Personne, on sérialise, on désérialize, et on regarde si on a le résultat attendu !
Le code est séparé en deux fichiers :
  1. sampleNode.cs : qui contient les type à sérialiser (Personne, Voiture)
  2. sampleProgram.cs : qui contient le code permettant d'effectuer les différentes étapes

La classe Personne (extrait !)


La classe Voiture


Le programme de test


retour à l'index

Le mot de la fin

Conclusion

J'ai eu besoin dans le cadre d'un projet au cours de mes études de faire de la sérialisation XML en Java et C#, et cela m'a permit de découvrir (et de comparer) à quel point cela peut être facile en .NET.

J'espère que cet article vous sera utile si vous cherchez vous aussi à (dé)sérializer un flux XML.
Si vous avez des remarques concernant cet article ((im)précisions, remarques, ...) faites moi signe ;)!!

retour à l'index

Remerciements

Monsieur Laurent ELLERBACH, responsable relation études supérieures chez Microsoft France, pour ses idées et son soutien logistique.
Monsieur David EMSELLEM, ingénieur développeur à l'ESSI, pour son intérêt et sa sympathie.

retour à l'index

Sources

Sur le Web : Bibliographie :

retour à l'index





par Alain Vizzini (vizzini@essi.fr )
pour l'ESSI & Microsoft, création 21-01-2003, dernière màj 26-01-2003


pages vues depuis le 14 oct. 2002