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

C# Discussion :

Géneration d'une classe depuis sa définition en xml


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    profiler
    Inscrit en
    Février 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : profiler

    Informations forums :
    Inscription : Février 2008
    Messages : 84
    Par défaut Géneration d'une classe depuis sa définition en xml
    Bonjour

    Pour mon projet (<pub>un clone de Eye of the Beholder II => www.mimicprod.net</pub>), je dois mettre en place un système de script pour gérer les évènements dans le jeu.

    Je définis une interface IScriptAction suivante :
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    	/// <summary>
    	/// Abstract base class for event script actions
    	/// </summary>
    	public interface IScriptAction
    	{
     
    		/// <summary>
    		/// Run the script
    		/// </summary>
    		/// <returns>True on success</returns>
    		bool Run();
     
     
    		#region IO
     
     
    		/// <summary>
    		/// Loads a party
    		/// </summary>
    		/// <param name="filename">Xml data</param>
    		/// <returns>True if team successfuly loaded, otherwise false</returns>
    		bool Load(XmlNode xml);
     
     
    		/// <summary>
    		/// Saves the party
    		/// </summary>
    		/// <param name="filename">XmlWriter</param>
    		/// <returns></returns>
    		bool Save(XmlWriter writer);
     
     
    		#endregion
     
     
     
    		#region Properties
     
     
    		/// <summary>
    		/// Action's name
    		/// </summary>
    		string Name
    		{
    			get;
    		}
     
     
    		#endregion
    La méthode Run() permet d'exécuter le script en lui même.
    La propriété Name est le nom de l'action (par exemple "Teleport") et est unique au sein de toutes les actions possibles.
    Les méthodes Save() et Load() permette respectivement de sauvegarder et de charger les informations du script.

    Voici un exemple pour l'action Teleport qui téléporte le joueur dans un autre endroit du jeu :
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    	/// <summary>
    	/// Teleport the team
    	/// </summary>
    	public class ScriptTeleport : IScriptAction
    	{
     
     
    		/// <summary>
    		/// 
    		/// </summary>
    		/// <returns></returns>
    		public bool Run()
    		{
     
     
    			return false;
    		}
     
    		#region IO
     
     
    		/// <summary>
    		/// Loads a party
    		/// </summary>
    		/// <param name="filename">Xml data</param>
    		/// <returns>True if team successfuly loaded, otherwise false</returns>
    		public bool Load(XmlNode xml)
    		{
    			return true;
    		}
     
     
     
    		/// <summary>
    		/// Saves the party
    		/// </summary>
    		/// <param name="filename">XmlWriter</param>
    		/// <returns></returns>
    		public bool Save(XmlWriter writer)
    		{
    			return true;
    		}
     
     
    		#endregion
     
     
     
    		#region Properties
     
     
    		/// <summary>
    		/// Target destination
    		/// </summary>
    		public DungeonLocation Target
    		{
    			get;
    			set;
    		}
     
     
    		/// <summary>
    		/// Change direction
    		/// </summary>
    		public bool ChangeDirection
    		{
    			get;
    			set;
    		}
     
     
    		/// <summary>
    		/// Action's name
    		/// </summary>
    		public string Name
    		{
    			get
    			{
    				return "Teleport";
    			}
    		}
     
     
    		#endregion
    	}
    Voici un exemple de sa définition en XML
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <action type="Teleport">
    	<target maze="test" x="10" y="5" direction="North" position="NorthEast" />
    	<changedirection value="false" />
    </action>
    Ma question est : est-il possible de faire l'association de manière "propre" et si possible automatique entre ma classe TeleportAction et sa définition XML ?
    Actuellement je fais ainsi :

    - Je lis la balise "action", je sais donc que j'ai affaire à un action.
    - Je lis le champ type et je fais un bon gros if(type == "")... else if(type == "")... else if(type =="")

    Ce n'est pas ce qu'il y a de mieux...

    Merci

  2. #2
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Puisque le nom est unique tu peux rechercher l'élément directement en fonction du nom, avec une expression XPath.

    Par exemple l'expression XPath suivante permet de trouver tous les éléments action possédant un attribut type ayant la valeur "Teleport".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    //action[@type='Teleport']
    En partant du XML suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    string xml =
    @"<root>
        <action type=""Bidon"">
            <target maze=""test"" x=""10"" y=""5"" direction=""North"" position=""NorthEast"" />
            <changedirection value=""false"" />
        </action>
        <action type=""Teleport"">
            <target maze=""test"" x=""10"" y=""5"" direction=""North"" position=""NorthEast"" />
            <changedirection value=""false"" />
        </action>
    </root>";
    Un exemple avec XPathDocument
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    XPathDocument xpathDoc = new XPathDocument(new StringReader(xml));
     
    XPathNodeIterator itor = xpathDoc.CreateNavigator().Select("//action[@type='Teleport']");
    if (itor.Count != 0 && itor.MoveNext())
    {
        // itor.Current donne accès à l'élément action qui va bien.
    }
    Et avec XmlDocument
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xml);
     
    XmlNode action = xmlDoc.SelectSingleNode("//action[@type='Teleport']");
    XPathDocument donne un accès en lecture seule uniquement. Tout le document n'est pas chargé en mémoire, contrairement à XmlDocument. Donc c'est plus léger en mémoire et plus rapide niveau traitement (idéal pour de la lecture donc).

    On peut aussi utiliser Linq To Xml.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    XDocument xDoc = XDocument.Load(new StringReader(xml));
     
    var result = (from action in xDoc.Descendants("action")
                    where action.Attribute("type").Value == "Teleport"
                    select action).FirstOrDefault();

  3. #3
    Membre confirmé
    Profil pro
    profiler
    Inscrit en
    Février 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : profiler

    Informations forums :
    Inscription : Février 2008
    Messages : 84
    Par défaut
    Ta solution est intéressante, mais je ne pense pas que "tel quel" ça va m'aider car je lis le flux xml un peu comme une page html. Je ne sais pas quels sont les éléments que je vais rencontrer. Or, avec ta méthode, je dois chercher les éléments. De plus, il faut que je garde l'ordre d'arrivée des actions ('H', puis 'L', puis 'C' et non pas dans mon ordre de recherche).

  4. #4
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Citation Envoyé par iliak Voir le message
    Ta solution est intéressante, mais je ne pense pas que "tel quel" ça va m'aider car je lis le flux xml un peu comme une page html. Je ne sais pas quels sont les éléments que je vais rencontrer. Or, avec ta méthode, je dois chercher les éléments. De plus, il faut que je garde l'ordre d'arrivée des actions ('H', puis 'L', puis 'C' et non pas dans mon ordre de recherche).
    Effectivement, dans ce contexte ce n'est plus trop adapté. Il aurait fallu préciser ce point dès le début ^^

    Sinon la sérialisation XML pourrait être intéressante comme l'indique Jerede, mais ça impliquerait que le XML change un peu et d'avoir une classe abstraite au lieu de l'interface (on ne peut pas sérialiser une interface). Au final tu aurais une liste d'actions, la sérialisation sauvegarde cette liste vers du XML et la désérialisation recrée ta liste à partir du XML.

    http://tlevesque.developpez.com/dotn...serialization/
    http://tlevesque.developpez.com/dotn...rialization-2/

  5. #5
    Membre confirmé
    Profil pro
    profiler
    Inscrit en
    Février 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : profiler

    Informations forums :
    Inscription : Février 2008
    Messages : 84
    Par défaut
    Citation Envoyé par StormimOn Voir le message
    Effectivement, dans ce contexte ce n'est plus trop adapté. Il aurait fallu préciser ce point dès le début ^^

    Sinon la sérialisation XML pourrait être intéressante comme l'indique Jerede, mais ça impliquerait que le XML change un peu et d'avoir une classe abstraite au lieu de l'interface (on ne peut pas sérialiser une interface). Au final tu aurais une liste d'actions, la sérialisation sauvegarde cette liste vers du XML et la désérialisation recrée ta liste à partir du XML.

    http://tlevesque.developpez.com/dotn...serialization/
    http://tlevesque.developpez.com/dotn...rialization-2/
    Je peux changer mon interface par une classe abstraite, ce n'est pas un problème. Je vais lire les liens, je verrais bien ce que je peux en tirer.

    Merci

    Suite au prochain épisode !

    PS: A ceux qui seraient intéressé par mon projet, je suis ouvert à toute proposition...

  6. #6
    Membre confirmé
    Profil pro
    profiler
    Inscrit en
    Février 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : profiler

    Informations forums :
    Inscription : Février 2008
    Messages : 84
    Par défaut
    Liens très intéressants, merci !

    Petite question. J'ai la définition suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <blocks width="20" height="30">
    	<block>
    		<location maze="test" x="0" y="0" direction="North" position="NorthEast" />
    		<type value="Ground" />
    		<nomonster value="False" />
    		<noghost value="False" />
    	</block>
    	<block>...</block>
    	...
    </blocks>
    Dans le bloc "<blocks>" j'ai deux attributs (width & height) qui m'indiquent la taille d'un "List<<List> Block> blocks" (qui contient tous les blocs d'un niveau, et je lis les données via un blocks[x][y]). Je me sers des coordonnées de <location....> pour connaitre l'emplacement exact de ce bloc dans la liste des blocs.

    Si je passe par la sérialisation XML, je ne vais plus pouvoir continuer ainsi...

  7. #7
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Il faudra sûrement adapter ton modèle pour que cela passe, et ça peut faire beaucoup de modifications à l'usage.

    Avant d'aller plus loin, as-tu vraiment besoin d'utiliser du XML comme support ? Histoire de voir si on peut trouver d'autres pistes à ce moment.

  8. #8
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Citation Envoyé par iliak Voir le message
    Si je passe par la sérialisation XML, je ne vais plus pouvoir continuer ainsi...
    Si tu passes par la sérialisation, le XML est dépendant de ton modèle (tes objets et comment ils sont organisés) bien que l'on puisse avec les attributs imposer certaines écritures (définir le nom des balises, définir une propriété en tant qu'attribut XML...). Le XML sérialisé sera au final différent de celui que tu as actuellement.

    Par exemple au lieu d'avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <blocks width="20" height="30">
    </blocks>
    Tu aurais plutôt quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <blocks>
        <size>
            <width>20</width>
            <height>30</height>
        </size>
    </blocks>
    Si cela pose un problème que le XML soit différent de celui actuel alors oubli la sérialisation. Sinon, essaye de sérialiser un objet Maze pour voir ce que cela donne.

  9. #9
    Membre chevronné Avatar de Jerede
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2010
    Messages
    271
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2010
    Messages : 271
    Par défaut
    Ou tu remplaces ton interface par une classe abstraite et tu serialize/désérialize avec le Serializer .NET

  10. #10
    Membre confirmé
    Profil pro
    profiler
    Inscrit en
    Février 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : profiler

    Informations forums :
    Inscription : Février 2008
    Messages : 84
    Par défaut
    Citation Envoyé par Jerede Voir le message
    Ou tu remplaces ton interface par une classe abstraite et tu serialize/désérialize avec le Serializer .NET
    Comment ça se passe lorsque je fais évoluer ma classe (ajout / suppression de propriétés par ex) ?

Discussions similaires

  1. STL list : acceder aux enfant d'une class depuis un liste
    Par poussinphp dans le forum SL & STL
    Réponses: 6
    Dernier message: 29/04/2007, 17h21
  2. Réponses: 5
    Dernier message: 23/04/2007, 16h31
  3. Lancer une class depuis une methode
    Par Bulscope dans le forum Langage
    Réponses: 2
    Dernier message: 31/12/2006, 10h23
  4. [AS2] Atteindre attribut d'une classe depuis une fonction interne a la classe
    Par Demco dans le forum ActionScript 1 & ActionScript 2
    Réponses: 6
    Dernier message: 18/04/2006, 21h03
  5. Réponses: 3
    Dernier message: 12/10/2005, 09h23

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