[Résolu] Variables dynamiques ?

Variables dynamiques ? [Résolu] - C#/.NET managed - Programmation

Marsh Posté le 04-05-2007 à 18:38:10    

Bonjour à tous,
 
J'aurai aimé savoir si les variables dynamiques existent en C# comme en PHP ?  
 
J'ai fais qqs recherches dessus mais apparemment y'a rien qui existe... ou peut-être utiliser des pointeurs ?
 
Voici mon pblm :

Code :
  1. //contient une liste d'objets
  2. ArrayList objList = new ArrayList();
  3. //création de l'objet
  4. MonObj obj = new MonObj();
  5. //ouverture d'un fichier XML
  6. XmlTextReader reader = new XmlTextReader("fichier.xml" );
  7.                
  8. //lit le fichier XML
  9. while (reader.Read())
  10. {
  11.     if (reader.MoveToContent() == XmlNodeType.Element)
  12.     {
  13.         //pour chaque élément "Truc" ou "Machin", renseigne la propriété du même nom de l'objet créé précédemment
  14.         switch(reader.Name)
  15.         {
  16.             case "Truc" : obj.truc = reader.ReadElementString();
  17.                 break;
  18.             case "Machin" : obj.machin = reader.ReadElementString();
  19.                 break;
  20.         }
  21.     }
  22.     else
  23.     {
  24.         reader.Read();
  25.     }
  26.     //une fois que les propriétés "truc" et "machin" de l'objet sont renseignées, ajoute l'objet à la liste
  27.     if(obj.truc != "" && obj.machin != "" )
  28.     {
  29.         objList.Add(obj);
  30.     }
  31. }


 
Voici mon fichier XML :

Code :
  1. <?xml version="1.0" encoding="utf-8" standalone="yes"?>
  2. <Liste>
  3.   <Objet Numéro="0">
  4.     <Truc>Chaîne 1</Truc>
  5.     <Machin>Chaîne 2</Machin>
  6.   </Objet>
  7.   <Objet Numéro="1">
  8.     <Truc>Chaîne 3</Truc>
  9.     <Machin>Chaîne 4</Machin>
  10.   </Objet>
  11. </Liste>


 
Je veux donc pouvoir lire le fichier XML et créer autant d'objets (en renseignant les propriétés de l'objet) qu'il y a de balises <Objet></Objet>. Là, tout se passe bien sauf que, lorsque je veux afficher les propriétés des objets contenus dans la liste, il m'affiche seulement le dernier objet créé. En fait, tous les objets ont les mêmes propriétés que le dernier objet. Bref, c'est pas encore très au point...
 
Si vous avez une petite idée, je suis preneur !
Merci d'avance,
Lionel.


Message édité par pot2yaourt le 04-05-2007 à 20:54:12
Reply

Marsh Posté le 04-05-2007 à 18:38:10   

Reply

Marsh Posté le 04-05-2007 à 18:56:16    

Hello,
 
Tu ne crées ton objet qu'une fois, tu dois déplacer la ligne  
5. MonObj obj = new MonObj();
 
dans ta boucle pour crée un nouvel objet à chaque fois.
 

Code :
  1. while (reader.Read())
  2. {
  3.    if (reader.MoveToContent() == XmlNodeType.Element)
  4.    {
  5.        MonObj obj = new MonObj();
  6.        //pour chaque élément "Truc" ou "Machin", renseigne la propriété du même nom de l'objet créé précédemment
  7.        switch(reader.Name)
  8.        {
  9.            case "Truc" : obj.truc = reader.ReadElementString();
  10.                break;
  11.            case "Machin" : obj.machin = reader.ReadElementString();
  12.                break;
  13.        }
  14.       //une fois que les propriétés "truc" et "machin" de l'objet sont renseignées, ajoute l'objet à la liste
  15.        objList.Add(obj);
  16.    }
  17.    else
  18.    {
  19.        reader.Read();
  20.    }
  21. }


 
A+
--
Mickaël
MyFinder, explorateur de fichier alternatif


Message édité par mikyfpc le 04-05-2007 à 18:56:58
Reply

Marsh Posté le 04-05-2007 à 19:17:08    

Salut,
 
Merci pour ta réponse aussi rapide !
 
Toutefois, ça ne fonctionne pas tout à fait...  :cry:  
En fait, dans ce cas, il y aura autant d'objets créés que d'éléments dans le fichier XML. En supposant qu'il y ait aussi une balise <Bidule></Bidule> dans le fichier XML, même si je ne le traîte pas dans le switch, un objet sera créé vu qu'il passera dans le if du dessus.
Du coup, chaque objet aura une de ses propriété renseignée : un premier objet aura sa propriété "truc" renseignée, sur un autre objet ça sera la propriété "machin", etc... et vu qu'aucun objet n'aura à la fois sa propriété "truc" ET sa propriété "machin" renseignée, alors aucun objet ne sera ajouté à la liste des objets.
 
Mais si t'as d'autres idées, je reste preneur !!  
Lionel.

Reply

Marsh Posté le 04-05-2007 à 20:27:15    

Voilà une autre proposition :
 
 

Code :
  1. MonObj obj = null;
  2. while (reader.Read())
  3. {
  4.    if (reader.MoveToContent() == XmlNodeType.Element)
  5.    {
  6.      
  7.        //pour chaque élément "Truc" ou "Machin", renseigne la propriété du même nom de l'objet créé précédemment
  8.        switch(reader.Name)
  9.        {
  10.            case "Truc" :
  11.             obj = new MonObj();
  12.             obj.truc = reader.ReadElementString();
  13.                break;
  14.            case "Machin" :
  15.             obj = new MonObj();
  16.             obj.machin = reader.ReadElementString();
  17.                break;
  18.        }
  19.       if( obj != null )
  20.       {
  21.       //une fois que les propriétés "truc" et "machin" de l'objet sont renseignées, ajoute l'objet à la liste
  22.        objList.Add(obj);
  23.      }
  24.    }
  25.    else
  26.    {
  27.        reader.Read();
  28.    }
  29. }


 
Sinon, une autre méthode, si tu connais les bases de données, tu peux lire un fichier XML en utilisant un dataset, et accéder à son contenu avec les datatables et datarow. ( voir DataSet.ReadXml)
 
A+
--
Mickaël
MyFinder, explorateur de fichier alternatif

Reply

Marsh Posté le 04-05-2007 à 20:52:45    

Entre temps, je suis arrivé à mes fins :
 

Code :
  1. MonObj obj = null;
  2. while (reader.Read())
  3. {
  4.     if (reader.MoveToContent() == XmlNodeType.Element)
  5.     {     
  6.         //pour chaque élément "Truc" ou "Machin", renseigne la propriété du même nom de l'objet créé précédemment
  7.         switch(reader.Name)
  8.         {
  9.             case "Truc" :
  10.                 //ne crée l'objet qu'une seule fois
  11.                 if(obj == null) obj = new MonObj();
  12.                 obj.truc = reader.ReadElementString();
  13.                 break;
  14.             case "Machin" :
  15.                 if(obj == null) obj = new MonObj();
  16.                 obj.machin = reader.ReadElementString();
  17.                 break;
  18.         }
  19.         if( obj != null )
  20.         {
  21.             if(obj.truc != "" && obj.machin != "" )
  22.             {
  23.                 //une fois que les propriétés "truc" et "machin" de l'objet sont renseignées, ajoute l'objet à la liste
  24.                 objList.Add(obj);
  25.                 //supprime l'objet en cours une fois ajouté
  26.                 obj = null;
  27.             }
  28.         }
  29.     }
  30.     else
  31.     {
  32.         reader.Read();
  33.     }
  34. }


 
Merci pour ton aide !
Lionel.

Reply

Marsh Posté le 04-05-2007 à 20:56:40    

Pourquoi ne pas utiliser simplement les fonctionnalités XML dont dispose C# ?
 
(anyway, t'as une solution dans mon exemple pour remplir ta liste même si tu ne veux pas bénéficier des avantages du truc)
 
program.cs (fichier principal)

Code :
  1. using System;
  2.  
  3. namespace XmlList
  4. {
  5.    class Program
  6.    {
  7.        static void Main(string[] args)
  8.        {
  9.            int line = 0;
  10.            Console.Clear();
  11.            Console.BackgroundColor = ConsoleColor.Red;
  12.            Console.ForegroundColor = ConsoleColor.Yellow;
  13.            Console.WriteLine("Machin    Truc      " );
  14.            Console.ResetColor();
  15.            foreach (Bidule b in ToolBox.InitListe(@"c:\in\tt.xml" ))
  16.            {
  17.                line++;
  18.                Console.SetCursorPosition(0, line);
  19.                Console.Write(b.machin);
  20.                Console.SetCursorPosition(10, line);
  21.                Console.Write(b.truc);
  22.            }
  23.            Console.ReadKey(true);
  24.        }
  25.    }
  26. }


 
maClass.cs (le truc qui t'intéresse)

Code :
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Xml;
  4.  
  5. public struct Bidule
  6. {
  7.    public string machin;
  8.    public string truc;
  9.  
  10.    // Une struct en C# (type valeur) peut contenir des méthodes et un constructeur
  11.    public Bidule(string valMachin, string valTruc)
  12.    {
  13.        this.machin = valMachin;
  14.        this.truc = valTruc;
  15.    }
  16. }
  17.  
  18. public abstract class ToolBox
  19. {
  20.    public static List<Bidule> InitListe(string xmlFileName)
  21.    {
  22.        XmlDocument dom = new XmlDocument();
  23.        List<Bidule> tmp = new List<Bidule>();
  24.  
  25.        dom.Load(xmlFileName);
  26.  
  27.        foreach (XmlNode nd in dom.SelectNodes("/Liste/Objet" ))
  28.        {
  29.            tmp.Add(new Bidule(nd.SelectSingleNode("Machin" ).InnerText, nd.SelectSingleNode("Truc" ).InnerText));
  30.        }
  31.  
  32.        return tmp;
  33.    }
  34. }


 
Sortie (avec ton fichier XML d'exemple) :
http://img69.imageshack.us/img69/6258/toolboxaf4.png
 
C'est zouli hein ? :D

Reply

Marsh Posté le 04-05-2007 à 21:06:36    

Sinon, si tu tiens vraiment à utiliser un XmlTextReader... [:cerveau heink]
 

Code :
  1. public static List<Bidule> InitListe2(string xmlFilename)
  2.    {
  3.        XmlTextReader reader;
  4.        List<Bidule> tmp = new List<Bidule>();
  5.  
  6.        reader = new XmlTextReader(xmlFilename);
  7.        Bidule b = new Bidule();
  8.  
  9.        while (reader.Read())
  10.        {
  11.            //pour chaque élément "Truc" ou "Machin", renseigne la propriété du même nom de l'objet créé précédemment
  12.            switch (reader.Name)
  13.            {
  14.                case "Truc":
  15.                    b.truc = reader.ReadElementString();
  16.                    break;
  17.                case "Machin":
  18.                    b.machin = reader.ReadElementString();
  19.                    break;
  20.            }
  21.  
  22.            if (b.machin != null && b.truc != null)
  23.            {
  24.                tmp.Add(b);
  25.                b = new Bidule();
  26.            }
  27.        }
  28.  
  29.        return tmp;
  30.    }

Reply

Marsh Posté le 05-05-2007 à 09:29:12    

Pfiou !! Là, je vois qu'il y a de la maîtrise !  :sweat:  
 
Bon, pour ma part je débute en C#... donc, d'avance stp, pardonne mon ignorance si mon code te paraît un peu "bizarre".
 
Apparemment, XmlTextReader n'est pas ton ami, lol !  :D C'est pas une bonne méthode ?
En fait je l'ai utilisé suite à un exemple trouvé dans un bouquin, mais j'aurai peut-être du approfondir un peu plus. J'ai vu effectivement que le "if (reader.MoveToContent() == XmlNodeType.Element)" ne servait à rien dans mon cas.
 
Je vais me replonger dans mes bouquins et potasser un peu l'utilisation des List<> et XmlDocument...
 
En tous cas merci pour ton aide !  :jap:  
Lionel.

Reply

Marsh Posté le 09-05-2007 à 09:52:18    

Pour ce qui est du XmlTextReader, je suppose qu'il a une utilité. Certainement en ce qui concerne les performances. Mais c'est au détriment de la souplesse d'utilisation (utilisation d'une structure arborescente, requêtes XPath, etc.)
 
Personnellement, je ne l'ai absolument jamais utilisé. Qui à faire dans la performance, autant lire avec un TextReader comme un gros bourrin à ce moment. Pour le reste, je préconise largement l'utilisation du modèle DOM (Data Object Model) qui permet la représentation d'un document XML en arbre d'objets.
 
Tu peux faire un tour sur W3Schools pour avoir plus d'infos sur DOM (à la fois le XML en général, et le modèle objet de MSXML) <- effectivement, le second intérêt de DOM, c'est qu'il repose sur MSXML, ce qui permet un portage du même code sur l'intégralité des langages tournant sur plateforme Windows.
 
Sinon, pour List<type> il s'agit simplement d'une liste chaînée indexable. le <type> implique l'utilisation obligatoirement du type en question, ce qui permet d'être certain de ne pas tomber sur un objet de type différent en plein milieu de la lecture.
 
List<> s'utilise donc comme un simple collection (variables de session, etc. par exemple), mais exige l'utilisation du type choisi à l'initialisation alors qu'une collection classique n'est pas typée.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed