Salut
-----
Je rencontre un petit souci avec des classes que je sérialise en XML
J'ai besoin de sérialiser des propriétés non accessibles en écriture, j'ai donc implémenté l'interface IXmlSerializable dans ma classe, et je stocke tous les infos utiles sous forme d'un simple tableau d'entiers.
Le reader est rédigé comme ceci (j'ai essayé plusieurs méthode, avec le même résultat) :
Et le désérialiseur correspond à 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
15
16 public void ReadXml(System.Xml.XmlReader reader) { while (reader.Read()) // parcourir tout le fichier if (reader.NodeType == XmlNodeType.Element) // si trouvé un élément actif { if (reader.Name == "ArrayOfInt") // si trouvé la balise de début des infos utiles { // créer le désérialiseur XmlSerializer xs = new XmlSerializer(typeof(int[])); // Désérialiser et si vérif ok, affecter les données // si pas OK, exception dans Verify.. catchée dans DomocanSerializer VerifyArrayAndSet( xs.Deserialize(reader) as int[]); } } }
Lorsque je sérialise puis désérialise une instance de ma classe, tout se passe parfaitement bien, je récupère mon instance à la dé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 public static T DeserializeXml<T>(string fileName) { T result = default(T); FileStream fileReader = null; XmlReader reader = null; try { fileReader = new FileStream(fileName, FileMode.Open); XmlSerializer deserializer = new XmlSerializer(typeof(T)); reader = new XmlTextReader(fileReader); result = (T)deserializer.Deserialize(reader); } catch { } finally { if (fileReader != null) fileReader.Close(); if (reader != null) reader.Close(); } return result; }
Si j'essaye de sérialiser un tableau d'instances de ma classe, tout semble également bien se passer, j'obtiens un fichier de ce type :
Par contre, à la désérialisation, j'obtiens un tableau d'un seul élément ne contenant qu'une seule instance (la dernière).
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 <?xml version="1.0" encoding="utf-8"?> <ArrayOfTrameCanWithRawData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <TrameCanWithRawData> <TrameRawArray> <ArrayOfInt> <int>80</int> <int>1</int> <int>0</int> <int>0</int> <int>-1</int> <int>-2</int> </ArrayOfInt> </TrameRawArray> </TrameCanWithRawData> <TrameCanWithRawData> <TrameRawArray> <ArrayOfInt> <int>80</int> <int>1</int> <int>0</int> <int>0</int> <int>0</int> <int>-3</int> </ArrayOfInt> </TrameRawArray> </TrameCanWithRawData> <TrameCanWithRawData xsi:nil="true" /> <TrameCanWithRawData xsi:nil="true" /> <TrameCanWithRawData xsi:nil="true" /> <TrameCanWithRawData xsi:nil="true" /> <TrameCanWithRawData xsi:nil="true" /> </ArrayOfTrameCanWithRawData>
Je m'attendais à ce que le désérialiseur crée une nouvelle référence de ma classe à chaque instance trouvée dans le fichier xml, et qu'il déclenche donc un readXml
Si je piste mon ReadXml, je vois qu'il parcours tout le fichier, et à chaque fois qu'il lit le tableau d'entiers, il affecte ce tableau à la référence en cours, toujours la même.
Bref, le "Readxml" est appelé une seule fois, pour une unique référence de ma classe, au lieu d'être appelé pour chaque référence du tableau de classes.
J'ai testé toutes sortes de choses après la ligne
VerifyArrayAndSet( xs.Deserialize(reader) as int[]);
de ReadXlm : return , reader.ReadSubtree etc, mais je n'ai rien trouvé qui force la génération d'autant d'instances qu'il y a d'entrées dans le fichier xml.
Quoi que je fasse, ma désérialisation ne me génère jamais qu'une seule instance de ma classe, fusse-t-elle dans un tableau.
Qu'ai-je oublié?
Merci d'avance,
Claude
PS: j'ai bien utilisé des méthodes alternatives, comme de détecter dans le Deserialize le type correspondant au tableau de classes, et ensuite de recopier mes classes dans un type sérialisable explicitement prévu, mais ce n'est évidemment pas élégant du tout, même si ça fonctionne.
Partager