Sérialiser une arraylist

Résolu
el_teedee Messages postés 497 Date d'inscription mercredi 7 juillet 2004 Statut Membre Dernière intervention 13 juillet 2015 - 22 juin 2005 à 17:09
scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017 - 8 févr. 2006 à 16:23
Bonjour,



alors, je viens de découvrir la sérialisation et juste après, j'ai découvert arraylist dont je ne méttais jamais servi.



Ce que je souhaite, c'est exporter en XML toutes les instances de ma
classe. Alors j'ai pensé mettre toutes ces instances dans un arraylist,
pour ensuite faire la sérialisation de toutes ces instances.

J'ai trouvé la méthode pour sérialiser un objet. Mais apparement, cela pose plus de problème pour un arraylist.



Le but de tout ça : je veux faire du stockage en dehors de mon appli,
je me suis orienté vers XML car je pense que cela correspond à mes
besoins, plus qu'une base de données.

Disons que j'ai une classe Fichier, dont chaque occurence possède 3 ou
4 propriétés d'un fichier. (numéro, statut, et nom du matériel)



Alors en fait, je télécharge d'un boîtier électronique une liste de fichiers avec leurs caractéristiques ci dessus. Je veux stocker cette liste à l'extérieur de l'application pour la retrouver au prochain lancement de cette dernière.

J'aurais donc par exemple dans l'ordre (n°, statut, nom):

instance1 : 1,statut1,machine1

instance2 : 2,statut2,machine2

instance3 : 3,statut2,machine1



Donc 3 instances de ma classe "fichier", que je voudrais pouvoir
retrouver lors de la prochaine exécution de l'appli. (et si possible,
les remettre dans des instances de fichier lors de la désérialisation)



J'arrive donc à la question : Quels est le format à adopter pour le
fichier XML (les balises, l'ordre, etc...car je ne sais pas du tout) et
comment envoyer dans un fichier XML toutes les instances de ma classe
fichier ? Est-ce que je peux passer par un arraylist ? Ou bien il faut
faire la sérialisation instance par instance ? (j'ai essayé cette
dernière solution, mais j'ai eu une erreur qui vient du format des
balises je pense)



Voilà ce que j'ai essayé :

private void ArrayListToXML_Click(object sender, System.EventArgs e)

{

XmlSerializer serialiseur = new XmlSerializer(typeof(Fichier));

TextWriter writer = new StreamWriter("monfichier.xml");

Fichier coucou;

foreach (object o in al)

{

coucou = (Fichier)o;

serialiseur.Serialize(writer,coucou);

}

writer.Close();

}



Alors, avec une seule instance dans l'arraylist, ca marche, voici le contenu du fichier XML :



<?xml
version="1.0" encoding="utf-8" ?>





[# -] <Fichier xmlns:xsd=" http://www.w3.org/2001/XMLSchema " xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance">






<numero>2</numero>





<date_debut>2005-06-22T17:02:52.3750000+02:00</date_debut>





<date_fin>2005-06-22T17:02:52.3750000+02:00</date_fin>





<duree>60</duree>





<statut>nouveau</statut>





<materiel>Epandeur 1</materiel>



</Fichier>




Mais, lorsque je crée une deuxième instance, voilà ce que j'obtient dans le contenu du fichier XML :

La page XML ne peut pas être affichée

Impossible d'afficher l'entrée XML en
utilisant la feuille de style XSL. Corrigez l'erreur, puis cliquez sur le bouton
[javascript:location.reload() Actualiser] ou réessayez
ultérieurement.


<hr>

Un seul élément de niveau supérieur est
autorisé dans un document XML. Erreur de traitement de la ressource
file:///D:/SATt...


<Fichier xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-^


Si vous en avoir une réponse, moi y'en a écouter vous avec plaisir.



Au passage, je pense que TheSaib a de l'info la dessus, j'ai vu un post à lui qui disait que arraylist n'est pas serialisable. Si tu peux me renseigner un peu plus

26 réponses

scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017
24 juin 2005 à 11:25
Bidou>le pb c qu'avec ta methode, on serialize la hashtable en dehors du fichier XML qu'on est en train d'écrire :(

----------------------------
C++ forever
C# amateur
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
24 juin 2005 à 13:43
Si tu veux sérializer une collection typée, alors il ne peut pas y avoir de hashtable dedans, d'un point de vue logique (évidemment que c'est faisable). Du coup, on ne se pause même pas la question si c'est faisable ou non de sérializer une collection qui contient en plus une hashtable... (mais à priori je ne vois pas pourquoi ça ne serait pas faisable).


Si maintenant tu veux sérializer une class qui contient un champ qui est une hashtable, pas de problème, la méthode que j'ai postée ci-dessus fonctionne sans soucis. J'ai fait un petit test super rapidement juste pour vérifier mes dires:


[Serializable()]
public class Test
{
private Hashtable t = new Hashtable();
private int i = 0;


public Test()
{
t.Add("a", "b");
}


public int I
{
get { return i; }
set { i = value; }
}


public Hashtable T
{
get { return t; }
set { t = value; }
}
}



public static void SaveFichier(string fileName, Test t)
{
SoapFormatter formatter = new SoapFormatter();


try
{
formatter.Serialize(new FileStream(fileName, FileMode.Create), t);
}
catch
{
throw;
}
finally
{
formatter = null;
}
}


Utilisation :


Test t = new Test();
SaveFichier(@"C:\test.xml", t);

[Pub] http://www.csharpfr.com/auteurdetail.aspx?ID=13319 [\Pub]
C# forever
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
24 juin 2005 à 13:53
Bon en fait je me suis peut-être un peu emballé sur le poste ci-dessus.
Si tu as une Hashtable dans ta collection (ce qui n'est peut-être pas aussi illogique que je le prétendais) alors tu peux faire comme ceci (j'ai modifié le code ci-dessus):


Rajouter :


[Serializable()]
public class TestCollection : System.Collections.CollectionBase
{
private Hashtable t = new Hashtable();
private int i = 0;


public TestCollection()
{
t.Add("Oui", "Non");
}


public void Add(Test t)
{
this.InnerList.Add(t);
}


public Test this[int i]
{
get { return (Test)this.InnerList[i]; }
}


public int I
{
get { return i; }
set { i = value; }
}


public Hashtable T
{
get { return t; }
set { t = value; }
}
}



Modifier :


public static void SaveFichier(string fileName, TestCollection tc)
{
SoapFormatter formatter = new SoapFormatter();


try
{
formatter.Serialize(new FileStream(fileName, FileMode.Create), tc);
}
catch
{
throw;
}
finally
{
formatter = null;
}
}


Utilisation :


Test t = new Test();
TestCollection tt = new TestCollection();
tt.Add(t);
SaveFichier(@"C:\test.xml", tt);

[Pub] http://www.csharpfr.com/auteurdetail.aspx?ID=13319 [\Pub]
C# forever
0
scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017
24 juin 2005 à 18:24
j'ai trouvé un lien intéressant :

http://aspzone.com/articles/167.aspx



à partir de la, je recrée une class de config qui permet d'indexer directement par la forme :



oColor = (Color)this["INIT"]["COLOR"]["BACKGROUND"].Value;



Le hic est dans (this.Value est de type object):

void System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter w)



if (this.Value != null)

{


// Ca marche mais que pour les type simple sinon j'ai le nom de la
class genre Color [Blue]


w.WriteAttributeString ("value", this.Value.ToString
());




// La ca marche plus, object peut etre une ArrayList, une Color...

/*w.WriteStartElement("value", NS);


XmlSerializer Serializer = new
XmlSerializer(typeof(object));

Serializer.Serialize(w, this.Value);

w.WriteEndElement();

*/

}



[...]

Serialize dictionary

----------------------------
C++ forever
C# amateur
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017
24 juin 2005 à 19:26
http://www.c2i.fr/code.aspx?IDCode=413



je viens de faire un test :



using System.Runtime.Serialization; // SOAP

using System.Runtime.Serialization.Formatters.Soap;



[Serializable()]

public class MonObjetASerialiserType : System.Collections.DictionaryBase, IXmlSerializable

{}



SoapFormatter oSOAPSerial = new SoapFormatter();

System.IO.FileStream oFS = new System.IO.FileStream(@"d:/output2.xml", FileMode.Create);

oSOAPSerial.Serialize(oFS, MonObjetASerialiser);

oFS.Close();

----------------------------
C++ forever
C# amateur
0
scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017
8 févr. 2006 à 16:23
voici un autre lien intéressant :

http://www.ftponline.com/vsm/2004_02/online/wahlin/

pour info on peut sérialiser une ArrayList de String sans ajouter le moindre code. Genre une arraylist de mails.
par contre si on passe par un objet intermédiaire qui contient 2 string (1 mail, 1 nom d'expéditeur) la on se tape une erreur de reflexion. (qui a dit que je réfléchis pas assez ? ;p)
donc visiblement mon objet intermédiaire doit implementer un peu de code.

----------------------------
C++ forever
C# amateur
0
Rejoignez-nous