Sauvegarde données d'une collection d'objets dans fichier .txt

GauloiZ-77 Messages postés 5 Date d'inscription mardi 30 juin 2015 Statut Membre Dernière intervention 3 juillet 2015 - 30 juin 2015 à 11:41
Vjjdgg Messages postés 2 Date d'inscription mercredi 4 novembre 2015 Statut Membre Dernière intervention 4 novembre 2015 - 4 nov. 2015 à 10:32
Bonjour,

Alors j'ai écris un programme qui permet de placer des points et des arcs sur un canvas.

Les objets Points et Arcs sont stockés dans des collections observables étant elles même stockées dans un objet Etage qui fait parti d'une collection d'étages étant elle même stockée dans un objet Projet.

J'aimerais pouvoir sauvegarder les données de ce projet (donc de ces collections) dans un fichier .txt (ou .xml mais cela a l'air beaucoup plus compliqué .. ) afin de pouvoir, en ouvrant ce fichier .txt, replacer les points et arcs sur leur coordonnées (x, y, z).

J'ai trouvé quelques petits éléments de réponses sur le site de Microsoft mais cela ne m'a pas beaucoup aidé :/

Est ce que quelqu'un pourrait m'aider :) ?

8 réponses

Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
30 juin 2015 à 13:38
Bonjour, le xml c'est assez simple, voir un exemple ici
http://codes-sources.commentcamarche.net/forum/affich-1561684-c-et-xml#8

Pour l'écriture de fichier texte en général, il y a de nombreux exemples dans les sources
http://codes-sources.commentcamarche.net/source/list/c-net-13/last
0
GauloiZ-77 Messages postés 5 Date d'inscription mardi 30 juin 2015 Statut Membre Dernière intervention 3 juillet 2015
1 juil. 2015 à 13:29
Merci Whismeril pour le XML, je vais essayer avec ça ^^

Mais pr le txt je ne trouve aps d'exemples qui me convienne :/
0
GauloiZ-77 Messages postés 5 Date d'inscription mardi 30 juin 2015 Statut Membre Dernière intervention 3 juillet 2015
1 juil. 2015 à 14:11
En fait ton exemple me montre un peu comment générer un fichier xml mais au niveau des from, in select c'est flou car je ne vois pas à quoi ça accède dans ton fichier c#
0
GauloiZ-77 Messages postés 5 Date d'inscription mardi 30 juin 2015 Statut Membre Dernière intervention 3 juillet 2015
1 juil. 2015 à 17:05
Re, je te montre ce que j'ai fait :

private void WriteXML()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.DefaultExt = ".xml";
ofd.Filter = "Fichiers XML (.xml)|*.xml";

if(ofd.ShowDialog() == true)
{
XDocument xDoc = new XDocument(new XElement("Nom Projet", NouveauProjet.NomProjet),
new XElement("Compteur Points", NouveauProjet.CompteurProjet.ComptePoint),
new XElement("Compteur Arcs", NouveauProjet.CompteurProjet.CompteArc),
new XElement("Etage", from MyEtages in NouveauProjet.CollecEtages
select new XElement("Nom Etage", Etage.Nom_Etage),
from Etages in NouveauProjet.CollecEtages
select new XElement("Numéro Etage", Etage.No_Etage),
from Etages in NouveauProjet.CollecEtages
select new XElement("Z Etage", Etage.Z_Etage)),

new XElement("Liste Points", from MyNoeud in Etage.CollecNoeuds
select new XElement("ID Point", MyNoeud.No_ID_Noeud),
from MyNoeud in Etage.CollecNoeuds
select new XElement("Coordonnées X, Y", MyNoeud.Coord_P),
from MyNoeud in Etage.CollecNoeuds
select new XElement("Coordonnées Z", MyNoeud.Coord_Z),
from MyNoeud in Etage.CollecNoeuds
select new XElement("No Etage", MyNoeud.No_Etage),
from MyNoeud in Etage.CollecNoeuds
select new XElement("Type Point", MyNoeud.TypeNoeud)),

new XElement("Liste Arcs", from MyArcs in Etage.CollecArcs
select new XElement("ID Arc", MyArcs.No_ID_Arc),
from MyArcs in Etage.CollecArcs
select new XElement("Type Arc", MyArcs.TypeArc),
from MyArcs in Etage.CollecArcs
select new XElement("Point 1 : ID", MyArcs.Node_D.No_ID_Noeud),
from MyArcs in Etage.CollecArcs
select new XElement("Point 1 : Coordonnées X, Y", MyArcs.Node_D.Coord_P),
from MyArcs in Etage.CollecArcs
select new XElement("Point 1 : Coordonnées Z", MyArcs.Node_D.Coord_Z),
from MyArcs in Etage.CollecArcs
select new XElement("Point 1 : No Etage", MyArcs.Node_D.No_Etage),
from MyArcs in Etage.CollecArcs
select new XElement("Point 1 : Type", MyArcs.Node_D.TypeNoeud),
from MyArcs in Etage.CollecArcs
select new XElement("Point 2", MyArcs.Node_F.No_ID_Noeud),
from MyArcs in Etage.CollecArcs
select new XElement("Point 2 : Coordonnées X, Y", MyArcs.Node_F.Coord_P),
from MyArcs in Etage.CollecArcs
select new XElement("Point 2 : Coordonnées Z", MyArcs.Node_F.Coord_Z),
from MyArcs in Etage.CollecArcs
select new XElement("Point 2 : No Etage", MyArcs.Node_F.No_Etage),
from MyArcs in Etage.CollecArcs
select new XElement("Point 2 : Type", MyArcs.Node_F.TypeNoeud)));

xDoc.AddFirst(new XComment("Ce fichier contient les données des différentes collections de points et d'arcs stockées dans les collections d'étages du projet"));

string NomFichier = ofd.FileName;
xDoc.Save(string.Format(NomFichier));
}
}


private void ReadXML()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Fichiers XML (.xml)|*.xml";

if (ofd.ShowDialog() == true)
{
string NomFichier = ofd.FileName;
XDocument xDoc = XDocument.Load(string.Format(NomFichier));

NouveauProjet.CollecEtages = (from MyEtages in xDoc.Descendants("Etage")
select new Etages
{
Nom_Etage = MyEtages.Element("Nom Etage").Value,
No_Etage = int.Parse(MyEtages.Element("Numéro Etage").Value),
Z_Etage = Double.Parse(MyEtages.Element("Z Etage").Value),
CollecNoeuds = (from MyNoeud in xDoc.Descendants("Liste Points")
select new Etages.ClassNoeuds
{
No_ID_Noeud = int.Parse(MyNoeud.Element("ID Point").Value),
Coord_P = Point.Parse(MyNoeud.Element("Coordonnées X").Value),
Coord_Z = Double.Parse(MyNoeud.Element("Coordonnées Z").Value),
No_Etage = int.Parse(MyNoeud.Element("No Etage").Value),
TypeNoeud = int.Parse(MyNoeud.Element("Type Point").Value),
}),
CollecArcs = (from MyArcs in xDoc.Descendants("Liste Arcs")
select new Etages.ClassArcs
{
No_ID_Arc = int.Parse(MyArcs.Element("ID Arc").Value),
TypeArc = int.Parse(MyArcs.Element("Type Arc").Value),
Node_D = new Etages.ClassNoeuds
{
No_ID_Noeud = int.Parse(MyArcs.Element("Point 1 : ID").Value),
Coord_P = Point.Parse(MyArcs.Element("Point 1 : Coordonnées X, Y").Value),
Coord_Z = Double.Parse(MyArcs.Element("Point 1 : Coordonnées Z").Value),
No_Etage = int.Parse(MyArcs.Element("Point 1 : No Etage").Value),
TypeNoeud = int.Parse(MyArcs.Element("Point 1 : Type").Value)
},
Node_F = new Etages.ClassNoeuds
{
No_ID_Noeud = int.Parse(MyArcs.Element("Point 2 : ID").Value),
Coord_P = Point.Parse(MyArcs.Element("Point 2 : Coordonnées X, Y").Value),
Coord_Z = Double.Parse(MyArcs.Element("Point 2 : Coordonnées Z").Value),
No_Etage = int.Parse(MyArcs.Element("Point 2 : No Etage").Value),
TypeNoeud = int.Parse(MyArcs.Element("Point 2 : Type").Value)
}
})
});
}
}


Dis moi ce que tu en penses, (je ne peux pas compiler encore à cause d'un problème de fichier XAML)

Mais le fait que mes collections observables fasse partie d'un objet qui fait également partie d'une collection observable me fait me poser la question : Est ce que chacune des collections de chaque objet va être écrite dans le fichier xml ?
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
1 juil. 2015 à 18:15
A première vue ca a l'air pas mal. Mais si tu as un message de problème xaml, c'est qu'il y a un problème de pré-compilation.
Je ne sais plus si c'est ici ou sur CCM/Programmation ou quelqu'un avait expliqué comment s'en affranchir.

Sinon tu peux faire un projet winform ou tu testes juste ce code.
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
1 juil. 2015 à 20:05
0
GauloiZ-77 Messages postés 5 Date d'inscription mardi 30 juin 2015 Statut Membre Dernière intervention 3 juillet 2015
3 juil. 2015 à 13:11
Yeah merci je vais jeter un oeil ^^
0
cgandco Messages postés 219 Date d'inscription mercredi 26 octobre 2011 Statut Membre Dernière intervention 22 juin 2017 9
3 juil. 2015 à 16:12
bonjour,

pour moi, le plus simple est de serialiser test objets en xml.

bon tuto ici :

http://tlevesque.developpez.com/dotnet/xml-serialization/


si tes attributs sont bien défini, en maximum 20 lignes tu peux lire et écrire ton fichier xml.

bonne journée

0
Yes merci !! ce tuto m'as beaucoup aidé, j'ai créée mes deux méthodes(SAve et Load) je vais voir si cela fonctionne et si dans le fichier .XML appairait bien l'ensemble des données de mes collections.

Car j'ai fait la méthode pour l'objet "Projet" qui contient une collection d'éléments contenant eux mêmes des collections ..
0

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

Posez votre question
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
3 juil. 2015 à 21:19
Oui, je suis d'accord avec cgandco pour la serialisation XML.
En plus, a la place de te palucher tout a la main (les attributs), tu peux créer un fichier de schéma XSD (Visual studio propose même un concepteur graphique !!).
Ensuite tu passes ce fichier XSD à l'utilitaires de ligne de commande XSD.EXE, tu auras ta classe C# toutes faite pour la serialisation XML.
Tu pourras ensuite la passer en paramètre d'un WebService, la transformer en Json pour la traiter en javascript ect...
C'est vraiment une très bonne méthode.

bye...
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
3 juil. 2015 à 22:28
Bonsoir,
attention toutefois, avec des collections dans les collections xmlserialiser est limité (2 niveaux si je me souviens bien), pas Linq...
0
cgandco Messages postés 219 Date d'inscription mercredi 26 octobre 2011 Statut Membre Dernière intervention 22 juin 2017 9
4 juil. 2015 à 11:40
bonjour Whismeril,

Je ne connais pas cette limitation, je vais la tester.

si elle existe rien n'empêche de sérialiser en deux fois ?

le gros avantage est que lorsque l'on modifie une propriété d'une des classes, cette modification sera directement faite dans le xml.

de plus il est facile de modifer la structure xml, par exemple un element devient l'attribut d'un autre ...

je vais tester ce soir ou demain la limitation du nombre de niveau de collection.

bonne journée.
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
4 juil. 2015 à 14:36
Je n'ai jamais pensé à le faire en deux fois.
J'ai eu aussi un autre problème avec un fichier sur réseau, je pense que xmlserialiser n'aime pas le lag.
Je n'ai pas eu le même souci avec Linq.

Pour modifier qui est attribut ou élément de qui c'est assez simple aussi.

En général, je mets 2 méthodes static dans la classe qui gèrent la serialisation et la desériliasation de la classe. Comme ça pareil, si un changement est fait sur la classe, on a la méthode sous la main.

Ça fait un moment que je pense à faire un tuto (aussi complet que possible) dessus. Dès que j'ai finit ma maison, je m'y mets (cet automne ou cet hiver en gros...)
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656 > Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024
7 oct. 2015 à 20:39
Bonjour, ça y est je l'ai fait ce tuto
http://codes-sources.commentcamarche.net/faq/11196-linq-to-xml-c-et-vb-net#serialisation

J'ai même découvert un outil qui permettrait (pas tester encore) de générer les classes à partir du xsd. Si ça marche bien, je mettrais à jour le tuto.
http://www.codeproject.com/Articles/30747/LINQ-to-XSD
0
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
4 juil. 2015 à 21:03
Salut,

je viens de faire l'exemple pour tester, et je n'ai pas eu de problème d'imbrication de collections.

De plus cette méthode est beaucoup moins verbeuse qu'avec linq, puisqu'on travaille directement sur nos objets ou objets tableau, que ce soit en création ou en utilisation.

//La sérialisation se fait en 3 lignes
FileStream  fs = new FileStream("projet.xml", FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(Projet));
serializer.Serialize(fs, ProjetInstance);


//4 lignes pour le chargement
StreamReader stream = new StreamReader("projet.xml", Encoding.UTF8);
XmlSerializer serializer = new XmlSerializer(typeof(Projet));
XmlTextReader reader = new XmlTextReader(stream.BaseStream);
Projet ProjetInstance = (Projet)serializer.Deserialize(reader);


le xsd donne un truc du gentre (que le début)

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Projet">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ListEtage">
          <xs:complexType>
            <xs:sequence>
              <xs:element maxOccurs="unbounded" name="Etage">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="ListPoint">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element maxOccurs="unbounded" name="Point">
                            <xs:complexType>
                              <xs:attribute name="_x" type="xs:integer" use="required" />
                              <xs:attribute name="_y" type="xs:integer" use="required" />
                            </xs:complexType>



la classe générée par xsd.exe, un truc du genre
(que le début aussi)


[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public class Projet
{
    private ProjetEtage[] _listeEtageField;
    private string _nameProjectField;

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("Etage", IsNullable = false)]
    public ProjetEtage[] ListEtage
    {
        get { return this._listeEtageField; }
        set{   this._listeEtageField = value;}
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string NameProject
    {
        get{  return this._nameProjectField; }
        set{  this._nameProjectField = value;}
    }
}


bye...
0
Whismeril Messages postés 19022 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 avril 2024 656
4 juil. 2015 à 21:47
Salut, jamais essayé avec le schéma et xsd.exe.
Je le faisais à la main.
Par contre, je ne mettais pas autant d'attribut en début de classe.
0
Je vais tester ton code et faire des essais avec mon projet et je te tiens au courant si cela fonctionne ^^
0
Vjjdgg Messages postés 2 Date d'inscription mercredi 4 novembre 2015 Statut Membre Dernière intervention 4 novembre 2015
4 nov. 2015 à 10:32
Merci beaucoup pour ce magnifique forum, je le trouve super bien.
0
Rejoignez-nous