|
|
La sérialisation (Marshaling) en XML en C# .Net 2.0
| |
Auteur : Emmanuel BLANCQUARD |
La sérialisation (Marshaling) est très répandu en programmation orientée objet. Elle consiste à encoder l’état d’un objet sous la forme d’un flux de données. Dans ce tutoriel nous allons découvrir la sérialisation XML d’un objet en C# .Net 2.0.
 |
Publicité
|
INTRODUCTION
La sérialisation (Marshaling) est un concept très répandu en programmation orientée objet. Elle consiste à encoder l’état d’un objet présent en mémoire sous la forme d’un flux de données. Ce flux de données peut être interprété de différentes façons selon la volonté du développeur. Dans ce tutoriel nous allons découvrir la sérialisation XML d’un objet simple puis un peu plus complexe en utilisant les composants standard du Framework .Net 2.0.
STRUCTURE D’UN FICHIER XML
XML (eXtensible Markup Language, langage de balisage extensible) est un langage de balisage générique. Le XML en tant que tel doit être vu comme un outil permettant de définir un langage (on parle ici de métalangage), permettant de créer des documents structurés à l'aide de balises.
En réalité un document XML est structuré en 3 parties :
- La première partie, appelée prologue permet d'indiquer la version de la norme XML utilisée pour créer le document (cette indication est obligatoire) ainsi que le jeu de caractères (en anglais encoding) utilisé dans le document (attribut facultatif, ici on spécifie qu'il s'agit du jeu ISO-8859-1, jeu LATIN, pour permettre de prendre en compte les accents français).
Ex : <?xml version="1.0" encoding="iso-8859-1"?>
Le prologue se poursuit avec des informations facultatives sur des instructions de traitement à destination d'applications particulières. Leur syntaxe est la suivante : <? Instructions de traitement ?>
- Le second élément est une déclaration de type de document (à l'aide d'un fichier annexe appelé DTD - Document Type Definition). Par exemple pour l’utilisation d’un XSD (XML Schema Description) mais nous n’allons pas rentrer dans ces détails là.
- Et enfin la dernière composante d'un fichier XML est l'arbre des éléments (comme celui ci-dessous) :
<Produits>
<Produit ID="01">
<Nom>Nom du produit</Nom>
<Description>Description du Produit</Description>
<Prix>Prix du Produit</Prix>
</Produit>
<Produit ID="02">
<Nom>Nom du produit</Nom>
<Description>Description du Produit</Description>
<Prix>Prix du Produit</Prix>
</Produit>
</Produits>
Nous avons le détail d’un listing de produit contenant un produit. La balise <Produits> est appelé la balise ROOT et contient des balises ELEMENT <Produit>. La base ELEMENT <Produit> comprend un ATTRIBUT « ID » et trois balises ELEMENT Nom, Description, Prix.
PROGRAMMATION C# .NET 2.0
En ce qui concerne la partie programmation nous pouvons créer des fichiers XML de X façons différentes, mais dans ce tutoriel nous n’utiliserons que la méthode du XML Sérialiser.
Cas simple :
Pour notre exemple, nous allons sérialiser un objet Produit de sorte que le fichier Xml de sortie ressemble a celui-ci :
<Produit>
<ID>1</ID>
<Nom>Nom du produit</Nom>
<Description>Description du Produit</Description>
<Prix>Prix du Produit</Prix>
</Produit>
Création de la class Produit :
public class Produit
{
private string m_strID;
private string m_strNom;
private string m_strDescription;
private float m_fPrix;
public Produit()
{}
}
Voici la classe produit dans son plus simple appareil. Telle qu’elle la sérialisation XML ne retournera que le nœud ROOT <Produit>. Par contre en modifiant la classe produit, en y ajoutant des propriétés publiques ainsi que les attributs de sérialisation, la classe Produit pourra être sérialisée correctement.
[Serializable]
[System.Xml.Serialization.XmlRoot()]
public class Produit
{
#region variables privées
private string m_strID;
private string m_strNom;
private string m_strDescription;
private float m_fPrix;
#endregion
#region propriétés
[System.Xml.Serialization.XmlAttribute()]
public string ID
{
get { return m_strID; }
set { m_strID = value; }
}
[System.Xml.Serialization.XmlElement()]
public string Nom
{
get { return m_strNom; }
set { m_strNom = value; }
}
[System.Xml.Serialization.XmlElement()]
public string Description
{
get { return m_strDescription; }
set { m_strDescription = value; }
}
[System.Xml.Serialization.XmlElement()]
public float Prix
{
get { return m_fPrix; }
set { m_fPrix = value; }
}
#endregion
#region constructeur
public Produit()
{}
#endregion
}
[Serializable] :
Renseigne que la classe est sérialisable.
[System.Xml.Serialization.XmlRoot()] :
Renseigne au sérialiser Xml qu’il s’agit du nœud ROOT il est facultatif, mais dans ses surcharges il permet de donner un nom au nœud différent de celui de la classe : [System.Xml.Serialization.XmlRoot("XmlProduct")]
[System.Xml.Serialization.XmlElement()] :
Renseigne au sérialiser Xml qu’il s’agit d’un élément à sérialiser. Il est facultatif, mais dans ses surcharges il permet de donner un nom au nœud différent de celui du membre. Attention seul un membre public peut être sérialisé et une propriété publique peut être sérialisée uniquement si elle possède les deux assesseurs {get ; set}. [System.Xml.Serialization.XmlElement("IdProduct")]
[System.Xml.Serialization.XmlIgnore()] :
Renseigne au sérialiser que le membre ne doit pas être sérialisé.
[XmlAttribute()] :
Renseigne au sérialiser que le membre doit être considéré comme un attribut.
Il existe bien plus d’attributs mais ce n’est pas le but de ce tutoriel de les exposer. Voici le lien vers le site MSDN de Microsoft où ces attributs sont expliqués : http://msdn2.microsoft.com/fr-fr/library/system.xml.serialization.xmlelementattribute(VS.80).aspx
Il nous suffit maintenant d’écrire deux méthodes qui vont nous permettre de sérialiser l’objet et de le dé sérialiser.
#region Méthode publique
public string Serialise()
{
try
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
System.Xml.Serialization.XmlSerializer serialiser = new System.Xml.Serialization.XmlSerializer(typeof(Produit));
serialiser.Serialize(ms, this);
return System.Text.Encoding.UTF8.GetString(ms.ToArray());
}
}
catch { return null; }
}
#endregion
#region Méthode statique publique
public static Produit DeSerialise(string _strXML)
{
if (_strXML != null)
{
byte[] arData = System.Text.Encoding.UTF8.GetBytes(_strXML);
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(arData.Length))
{
ms.Write(arData, 0, arData.Length);
System.Xml.Serialization.XmlSerializer serialiser = new System.Xml.Serialization.XmlSerializer(typeof(Produit));
ms.Seek(0, System.IO.SeekOrigin.Begin);
object obj = serialiser.Deserialize(ms);
if (obj is Produit)
return obj as Produit;
else
return null;
}
}
return null;
}
#endregion
Méthode Serialise : Instancier XmlSerialiser en renseignant le type de l’objet à sérialiser. Ensuite sérialiser en renseignant un Stream de destination (ce pourrait très bien être un File Stream et directement écrire dans un fichier), ici dans notre exemple on retourne une chaine de caractère correspondant au fichier Xml.
Méthode DeSerialise : On transforme le string passé en paramètre en tableau de byte, on le transforme ensuite en Stream afin de pouvoir passer ce flux au dé-sérialiser pour reconstruire l’objet. Attention il est primordial de réinitialiser le pointeur du Stream à 0 pour le dé-sérialiser.
Résultat obtenu après la sérialisation :
Grâce au code suivant nous allons mettre en évidence le XML généré par notre classe :
Produit MyProduct = new Produit();
MyProduct.Description = "description du produit";
MyProduct.ID = "1";
MyProduct.Nom = "Nom produit";
MyProduct.Prix = 123;
string _str = MyProduct.Serialise();
Création et remplissage de l’objet produit suivi de sa sérialisation. Le contenu du string _str :
<?xml version="1.0"?>
<Produit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="1">
<Nom>Nom produit</Nom>
<Description>description du produit</Description>
<Prix>123</Prix>
</Produit>
Cas multiple :
Nous allons maintenant voir un cas de sérialisation d’un objet contenant un autre objet à sérialiser. C’est par exemple le cas pour la sérialisation d’une liste. Nous allons pour ce faire utiliser une class ProductList qui contiendra une liste de produits et une date d’information sur cette liste.
[Serializable]
[System.Xml.Serialization.XmlRoot()]
public class ProductList
{
#region Variables privées
private DateTime m_dt;
private List<Produit> m_productlist;
#endregion
#region Propriétés
[System.Xml.Serialization.XmlElement("Date")]
public DateTime DT
{
get { return m_dt; }
set { m_dt = value; }
}
[System.Xml.Serialization.XmlArray("Liste")]
public List<Produit> PL
{
get { return m_productlist; }
set { m_productlist = value; }
}
#endregion
#region Constructeur
public ProductList()
{}
public ProductList(DateTime _dt)
{
}
#endregion
#region Méthode publique
public string SerialiseToXml()
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
System.Xml.Serialization.XmlSerializer serialiser = new System.Xml.Serialization.XmlSerializer(this.GetType());
serialiser.Serialize(ms, this);
return System.Text.Encoding.Default.GetString(ms.ToArray());
}
}
#endregion
#region Méthode statique publique
public static ProductList Deserialize(string _xml)
{
byte[] ardata = System.Text.Encoding.Default.GetBytes(_xml);
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
ms.Write(ardata, 0, ardata.Length);
ms.Seek(0, System.IO.SeekOrigin.Begin);
System.Xml.Serialization.XmlSerializer serialiser = new System.Xml.Serialization.XmlSerializer(typeof(ProductList));
object obj = serialiser.Deserialize(ms);
if (obj != null && obj is ProductList)
return obj as ProductList;
else
return null;
}
}
#endregion
}
Nous voyons apparaître une propriété PL qui est une List générique d’objet produit. Un attribut lui est attribué : [System.Xml.Serialization.XmlArray("Liste")] qui renseigne que la propriété est une liste et que le nom de la balise doit être Liste.
Résultat obtenu après sérialisation :
Grâce au code suivant nous allons permettre de mettre en évidence le XML généré par notre classe.
Produit p = new Produit();
p.ID = Guid.NewGuid().ToString();
p.Nom = "Nom1";
p.Description = "Description1";
p.Prix = 1;
//
Produit p2 = new Produit();
p2.ID = Guid.NewGuid().ToString();
p2.Nom = "Nom2";
p2.Description = "Description2";
p2.Prix = 2;
//
Produit p3 = new Produit();
p3.ID = Guid.NewGuid().ToString();
p3.Nom = "Nom3";
p3.Description = "Description3";
p3.Prix = 3;
//
List<Produit> pl = new List<Produit>();
pl.Add(p);
pl.Add(p2);
pl.Add(p3);
//
ProductList pl2 = new ProductList(DateTime.Now);
pl2.PL = pl;
//
txt_Rslt.Text = pl2.SerialiseToXml();
Création et remplissage de l’objet produit suivi de sa sérialisation. Et cela donne :
<?xml version="1.0"?>
<ProductList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Date>2008-08-12T12:23:22.2536419+02:00</Date>
<Liste>
<Produit ID="48b9e7aa-3177-49f1-bfb6-262695229a47">
<Nom>Nom1</Nom>
<Description>Description1</Description>
<Prix>1</Prix>
</Produit>
<Produit ID="8d130190-621a-470c-82e9-5a27507af972">
<Nom>Nom2</Nom>
<Description>Description2</Description>
<Prix>2</Prix>
</Produit>
<Produit ID="f967cc60-9be2-424e-a7d8-884a5e173e46">
<Nom>Nom3</Nom>
<Description>Description3</Description>
<Prix>3</Prix>
</Produit>
</Liste>
</ProductList>
|
A lire aussi sur Devparadise.com :
Création d’un menu déroulant en PHP et XML
Illustration de l’héritage de classe et de l’implémentation d’interface en c#...
Création d’une DLL en C# .Net 2.0
Visual C# 2008 Express : Installation et début de projet
A télécharger aussi sur Devparadise.com :
Sources de l'article sur la génération d'un menu avec xml et php
Source de l'article sur l’héritage de classe et de l’implémentation
Code Source : sérialisation (Marshaling) en C# .Net 2.0
Exemple de Dll .Net 2.0
Microsoft Visual C# 2008 Express Edition
|
|