IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Dotnet Discussion :

La sérialisation XML avec .NET [Tutoriel]


Sujet :

Dotnet

  1. #1
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut La sérialisation XML avec .NET
    Cette discussion est consacrée à l'article intitulé La sérialisation XML avec .NET. Vous pouvez y poster vos commentaires concernant l'article.

    Synopsis :
    Ce tutoriel explique comment sérialiser et désérialiser des objets en XML à l'aide des fonctionnalités du .NET Framework. On verra notamment comment contrôler très finement le schéma des documents XML générés par la sérialisation.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Excellent tuto !
    pdf aussitot enregistré dans mes documents
    Merci !

  3. #3
    Membre averti Avatar de roster
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 397
    Points : 426
    Points
    426
    Par défaut
    Merci bien!

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 273
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 273
    Points : 2 202
    Points
    2 202
    Par défaut
    +1 !

  5. #5
    Membre actif Avatar de AJemni
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2008
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2008
    Messages : 242
    Points : 290
    Points
    290
    Par défaut
    Franchement ce Tuto ma beaucoup aider et il m’a clarifié beaucoup d’ambiguité, mais en contre partie, la gestion d’héritage n’était pas trop claire pour moi.

    +1

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par AJemni Voir le message
    mais en contre partie, la gestion d’héritage n’était pas trop claire pour moi.
    En fait, c'est un problème qui n'est pas forcément évident à comprendre si on ne l'a pas déjà rencontré sur un cas concret... En tous cas, si tu veux des éclaircissements là-dessus, n'hésite pas à demander

  7. #7
    Membre du Club
    Inscrit en
    Novembre 2002
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 51
    Points : 57
    Points
    57
    Par défaut
    Très bon article.

    Une petite remarque cependant à propos de l'attribut Flags sur l'énumération :
    Remarquez l'attribut Flags sur l'énumération : il indique que les valeurs peuvent être combinées par un OU binaire (opérateur |). Cet attribut n'est habituellement pas obligatoire, mais il l'est dès lors qu'on veut sérialiser cette énumération en XML. Si l'attribut Flags n'est pas présent, une exception sera levée si on cherche à sérialiser une valeur qui ne fait pas explicitement partie de l'énumération.
    J'ai essayé de mettre ou supprimer l'attribut Flags au dessus de mon enum et cela n'a rien changé : j'ai quand même une exception lorsque je sérialise une valeur en dehors de l'enum.
    J'ai fait mes tests en .Net 2.0. Peut-être cela est-il différent pour les nouvelles versions mais cela m'étonnerais.

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par sylvain114d Voir le message
    J'ai fait mes tests en .Net 2.0. Peut-être cela est-il différent pour les nouvelles versions mais cela m'étonnerais.
    Bizarre... peux-tu montrer le code qui pose problème ?
    (par contre je pars en WE donc je ne pourrai pas regarder avant dimanche soir)

  9. #9
    Membre du Club
    Inscrit en
    Novembre 2002
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 51
    Points : 57
    Points
    57
    Par défaut
    J'ai une exception lors de la sérialisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
        [Flags]
        public enum AddressType
        {
            None = 0,
            Ship = 1,
            Bill = 2
        }
     
        public class Address
        {
            [XmlElement("TypeAdresse")]
            public AddressType Type;
            public string AdrLine1;
        }
     
        class XMLSerialTest
        {
            public static void Test()
            {
                Address a1 = new Address();
                a1.Type = (AddressType)10;
                a1.AdrLine1 = "Hello World!";
     
                XmlSerializer xs = new XmlSerializer(typeof(Address));
                using (StreamWriter wr = new StreamWriter("c:\\test.xml"))
                {
                    xs.Serialize(wr, a1);
                }
                using (StreamReader rd = new StreamReader("c:\\test.xml"))
                {
                    Address a2 = xs.Deserialize(rd) as Address;
                    Console.WriteLine("Type : " + a2.Type);
                    Console.WriteLine("Line1 : " + a2.AdrLine1);
                }
            }
        }

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Le problème est ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a1.Type = (AddressType)10;
    10 n'est pas une valeur valide de AddressType. Ca ne correspond à aucune combinaison de valeurs de AddressType... On peut sérialiser des valeurs qui ne font pas explicitement partie de l'enumération, mais il faut quand même que ce soit une combinaison de valeurs existantes...

  11. #11
    Membre du Club
    Inscrit en
    Novembre 2002
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 51
    Points : 57
    Points
    57
    Par défaut
    OK merci.
    Donc la sérialisation XML d'une enum avec l'attribut Flags fonctionne de façon intuitive et cohérente avec le reste du framework.
    Dans ton article j'avais l'impression que l'attribut Flags avait un comportement spécial lors de sérialisation XML.

    Les phrases :
    Cet attribut n'est habituellement pas obligatoire, mais il l'est dès lors qu'on veut sérialiser cette énumération en XML.
    et
    Si l'attribut Flags n'est pas présent, une exception sera levée si on cherche à sérialiser une valeur qui ne fait pas explicitement partie de l'énumération.
    m'ont induit en erreur.

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Ce que j'ai voulu dire, c'est que si tu essaies de combiner des valeurs d'enum alors que l'enum n'a pas l'attribut Flags, ça plante à la sérialisation

  13. #13
    Candidat au Club
    Homme Profil pro
    Concepteur Développeur Informatique
    Inscrit en
    Février 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Concepteur Développeur Informatique

    Informations forums :
    Inscription : Février 2015
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Le tutoriel est intéressant et complet, mais il manque de clarté à certains endroits.

    Par exemple, dans la section : I-A-2. Membres de type non-primitif.
    Lorsqu'il faut ajouter cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public Address Address { get; set; }
    Ce passage du tuto n'est pas assez explicite car elle n'indique pas assez précisément où il faut insérer le code.
    J'ai passé plusieurs minutes avant de comprendre qu'il fallait l'intégrer dans la classe Person à la suite des autres propriétés de la classe.

    Ensuite, dans la section : I-A-3. Sérialisation d'une collection.
    Il faut ajouter et remplacer du code.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public List<Address> Addresses { get; set; }
     
    // Et on n'oublie pas de l'initialiser dans le constructeur :
    public Person()
    {
        this.Addresses = new List<Address>();
    }
    Même chose ici, non seulement ce n'est pas assez explicite, mais en plus juste après cette phrase me laisse pantois :
    Je ne m'attarde pas sur le code de sérialisation, qui est identique à ce qu'on a déjà utilisé plus haut.
    Le code de sérialisation n'est visiblement pas identique, puisqu'on a changé les propriétés et pour ainsi dire l'utilisation de la classe Person. Du coup, je me retrouve non pas face à un tutoriel, mais face à une énigme : Comment doit-on réécrire l'utilisation de l'objet pour espérer obtenir le même résultat que dans le tutoriel ?

    Et cela m'amène à une autre problématique qui fait que je dois attendre une réponse avant de pouvoir suivre le reste du tutoriel car tous les exemples se basent sur les exemples précédents. L'idéal serait, à la fin de chaque section, de fournir le code complet afin d'être sûr de ne pas faire d'erreur.

    Merci d'avance.

  14. #14
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Lyonsbanner Voir le message
    Lorsqu'il faut ajouter cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public Address Address { get; set; }
    Ce passage du tuto n'est pas assez explicite car elle n'indique pas assez précisément où il faut insérer le code.
    J'ai passé plusieurs minutes avant de comprendre qu'il fallait l'intégrer dans la classe Person à la suite des autres propriétés de la classe.
    J'ai beau relire, je ne vois vraiment pas en quoi ce n'est pas clair. Le paragraphe au dessus du code explique sans ambigüité qu'on ajoute une nouvelle propriété Address à la classe Person.

    Dans notre exemple précédent, la classe Person est très simple, et n'a que des propriétés de type primitif (nombres et chaîne de caractères). Compliquons maintenant un peu les choses et voyons ce qu'il se passe lorsque notre classe a des propriétés de type plus complexe, par exemple une propriété Address :
    C'est vrai que je n'ai pas dit explicitement qu'on ajoute la propriété à la classe, mais tel que c'est formulé, je ne vois vraiment pas ce qu'on peut comprendre d'autre...

    Citation Envoyé par Lyonsbanner Voir le message
    Ensuite, dans la section : I-A-3. Sérialisation d'une collection.
    Il faut ajouter et remplacer du code.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public List<Address> Addresses { get; set; }
     
    // Et on n'oublie pas de l'initialiser dans le constructeur :
    public Person()
    {
        this.Addresses = new List<Address>();
    }
    Même chose ici, non seulement ce n'est pas assez explicite,
    Là encore, je ne vois pas le problème. Cette phrase décrit clairement la modification :

    on va remplacer la propriété Address par une propriété Addresses, de type List<Address>
    Et pour le constructeur qui a effectivement été ajouté, le commentaire dans le code n'est il pas suffisamment clair ?

    Comme indiqué au début, ce tuto s'adresse à des gens qui connaissent les bases de C#, et qui devraient donc reconnaitre un constructeur quand ils en voient un ; je ne décris pas chaque ligne de code, sinon le tuto serait interminable (et super ch***t à lire en plus...)

    Citation Envoyé par Lyonsbanner Voir le message
    Le code de sérialisation n'est visiblement pas identique, puisqu'on a changé les propriétés et pour ainsi dire l'utilisation de la classe Person. Du coup, je me retrouve non pas face à un tutoriel, mais face à une énigme : Comment doit-on réécrire l'utilisation de l'objet pour espérer obtenir le même résultat que dans le tutoriel ?
    Non, je maintiens, le code de sérialisation n'a pas changé ; c'est la classe elle-même qui a changé, pas le code à écrire pour en sérialiser une instance. Juste pour être sûr qu'on se comprenne bien, c'est de ce code que je parle :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        XmlSerializer xs = new XmlSerializer(typeof(Person));
        using (StreamWriter wr = new StreamWriter("person.xml"))
        {
            xs.Serialize(wr, p);
        }
    Le reste du code ne s'occupe pas de la sérialisation, c'est juste la structure de la classe.

    Citation Envoyé par Lyonsbanner Voir le message
    Et cela m'amène à une autre problématique qui fait que je dois attendre une réponse avant de pouvoir suivre le reste du tutoriel car tous les exemples se basent sur les exemples précédents.
    En fait je pense qu'il y a un malentendu sur la nature de l'article : tu essaies de le suivre comme si c'était un tuto "pas-à-pas", alors que ce n'est pas le cas. J'explique simplement comment faire telle ou telle chose, mais il n'y a pas vraiment de progression pour arriver à un résultat final ; chaque section décrit un scénario différent.

    Citation Envoyé par Lyonsbanner Voir le message
    L'idéal serait, à la fin de chaque section, de fournir le code complet afin d'être sûr de ne pas faire d'erreur.
    Ça aurait un sens si c'était un tuto pas-à-pas, mais comme dit plus haut, ce n'est pas le cas. Peut-être que j'aurais du faire ça, mais j'ai écrit ça il y a 6 ans, et très franchement je n'ai pas la motivation pour le retravailler...

    Si tu es bloqué sur un point précis, dis moi ce que c'est, je pourrai essayer de te débloquer.

  15. #15
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2007
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2007
    Messages : 871
    Points : 1 498
    Points
    1 498
    Par défaut
    Juste histoire d'enfoncer le clou:

    Merci tomlev pour ce tuto, je m'en sers souvent pour me souvenir de la syntaxe lors de serialisation.

    Effectivement tu n'abordes pas toutes les possibilites, mais tu vas a l'essentiel, et de mon point de vue personnel c'est l'un des tuto avec celui xpath et celui sur SOLID dont je me sers le plus souvent.

  16. #16
    Candidat au Club
    Homme Profil pro
    Concepteur Développeur Informatique
    Inscrit en
    Février 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Concepteur Développeur Informatique

    Informations forums :
    Inscription : Février 2015
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Non, je maintiens, le code de sérialisation n'a pas changé ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     XmlSerializer xs = new XmlSerializer(typeof(Person));
        using (StreamWriter wr = new StreamWriter("person.xml"))
        {
            xs.Serialize(wr, p);
        }
    Oui, effectivement. Cette partie du code de sérialisation n'a pas changé depuis le début, ça j'avais bien compris. Mais c'est dans la partie où on utilise les instances de classes que ça se gâte.

    Dans la section "I-A-2. Membres de type non-primitif", il y a ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Person p = new Person
        {
            Id = 123,
            LastName = "Dupond",
            FirstName = "Jean",
            Address = new Address
            {
                Street = "1, rue du petit pont",
                ZipCode = "75005",
                City = "Paris",
                Country = "France"
            }
        };
    Pas de problème de ce côté là.

    Ensuite, on a ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    List<Person> contactBook = new List<Person>();
     
        Person jean = ... // inutile de s'appesantir sur l'initialisation des objets...
        Person jacques = ...
     
        contactBoox.Add(jean);
        contactBoox.Add(jacques);
    Là encore c'est simple, il suffit de créer une nouvelle instance de Person avec les informations de Jacques.

    Mais après, lorsqu'on arrive au moment il faut mettre un type collection dans la classe Person, il n'y a pas d'exemple du tout. J'ai considéré qu'il suffisait de laisser le code que j'ai bidouillé (et dont je n'étais pas sûr), mais ça n'a pas marché car j'ai obtenu une erreur à ce niveau là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Address = new Address { [...] }
    Évidement, la propriété a changé et Address n'existe plus. Le gros problème, c'est que je ne savais pas quoi mettre à la place. J'ai donc dû travailler dessus et on m'a expliqué que la structure lors de l'utilisation des instances de classes était complètement différente. J'étais loin d'être sur la bonne voie.

    @mermich : Des possibilités, il y en a une infinité. Mais dès qu'on en présente une, et qu'on se retrouve face à une impasse insoupçonnée, l'essentiel d'un tutoriel ne suffit plus.

  17. #17
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    En fait, je suis passé rapidement sur tout ce qui n'était pas directement lié à la sérialisation (par exemple l'initialisation des objets), parce que ce n'était pas le sujet...

Discussions similaires

  1. manipulation XML avec vb.net
    Par etud_ini dans le forum VB.NET
    Réponses: 1
    Dernier message: 30/04/2009, 11h45
  2. Petit soucie de sérialisation avec .net remoting
    Par teddyalbina dans le forum C#
    Réponses: 2
    Dernier message: 22/03/2008, 21h34
  3. [C# 2.0] Sérialisation XML avec PCDATA
    Par stailer dans le forum C#
    Réponses: 2
    Dernier message: 07/01/2007, 22h52
  4. Réponses: 1
    Dernier message: 28/03/2006, 22h08
  5. [VB.NET] Sérialisation XML de Collections
    Par nico-pyright(c) dans le forum Windows Forms
    Réponses: 8
    Dernier message: 15/12/2004, 15h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo