Discussion: Parser un fichier xml

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    avril 2017
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : avril 2017
    Messages : 36
    Points : 33
    Points
    33

    Par défaut Parser un fichier xml

    Bonjour,

    Je débute en C# et j'ai besoin de récupérer certaines informations contenues dans un fichier *.xml.

    Je compte récupérer le fichier à l'aide de la classe OpenDialog cependant sur plusieurs exemples que j'ai vu. Tous utilise la classe ParseFile.

    Voilà ma question est ce la bonne manière pour moi de récupérer certaines informations de mon fichier ?

    Merci

  2. #2
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    février 2010
    Messages
    3 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : février 2010
    Messages : 3 414
    Points : 9 039
    Points
    9 039
    Billets dans le blog
    3

    Par défaut

    Citation Envoyé par didio Voir le message
    Tous utilise la classe ParseFile.
    Ah, je ne connais pas cette classe

    Pour lire un fichier XML, c'est tout simple. Quand tu appelles la fonction OpenFile() sur ton objet OpenFileDialog, elle te retourne un Stream. Il te suffit de lire ce Stream :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    var xDoc = XDocument.Load(tonStream);
    Ci-dessus on utilise Linq to XML, qui n'est disponible qu'a partir de la version 3.5 du framework .NET.

    Si tu utilises un framework <= 3.0, tu dois faire comme ceci :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var xmlDoc = new XmlDocument();
    xmlDoc.Load(tonStream);

    Ensuite il te reste a lire ton fichier pour faire ce que tu souhaites.
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige

  3. #3
    Membre chevronné
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    mars 2005
    Messages
    1 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2005
    Messages : 1 122
    Points : 1 787
    Points
    1 787

    Par défaut

    Ou sinon, tu créé une ossature en objet correspondant à ton schéma XML et tu déserialise.

    Par exemple pour le XML suivant :
    Code XML : 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
    <?xml version="1.0" encoding="UTF-8"?>
    <Annuaire departement="69" annee="2018">
    	<Villes>
    		<Ville codepostal="69000" nom="Lyon">
    			<Personnes>
    				<personne nom="toto", prenom="popo">
    					<Rue1>12, avenue du développement Delphi</Rue1>
    					<Rue2 />
    					<Rue3 />
    					<Fixe>0426000000</Fixe>
    					<Fax>0426000000</Fax>
    					<Site>www.developpez.com</Site>
    				</personne>
    			</Personnes>
    		</Ville> 
    	</Villes>
    </Annuaire>

    On déclaré les classes suivantes :
    Code C# : 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
    public class Annuaire
    {
        [XmlAttribute("departement")]
        public String Departement { get; set; }
     
        [XmlAttribute("annee")]
        public UInt32 Annee { get; set; }
     
        [XmlArrayItem("Ville")]
        public List<Ville> Villes = new List<Ville>();
    }
     
    public class Ville
    {
        [XmlAttribute("codepostal")]
        public String CodePostal { get; set; }
     
        [XmlAttribute("nom")]
        public String Nom { get; set; }
     
        [XmlArrayItem("Personne")]
        public List<Personne> Personnes = new List<Personne>();
    }
     
    public class Personne
    {
        public String Rue1 { get; set; }
     
        public String Rue2 { get; set; }
     
        public String Rue3 { get; set; }
     
        public String Fixe { get; set; }
     
        public String Fax { get; set; }
     
        public String Site { get; set; }
    }

    Et on déserialise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Annuaire annuaire = null;
    using (var stream = new StreamReader("Annuaire.xml"))
    {
        var serialiser = new XmlSerializer(typeof(Annuaire));
        annuaire = (Annuaire)serialiser.Deserialize(stream);
    }

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    avril 2017
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : avril 2017
    Messages : 36
    Points : 33
    Points
    33

    Par défaut

    Nickel.

    Merci beaucoup je vais partir là dessus.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    avril 2017
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : avril 2017
    Messages : 36
    Points : 33
    Points
    33

    Par défaut

    Bonjour,

    Je reviens la dessus, il se trouve que mon xml à la forme 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
    <?xml version="1.0" encoding="UTF-8"?>
    <Annuaire departement="69" annee="2018">
    	<Villes>
    		<Ville codepostal="69000" nom="Lyon">
    			<Personnes>
                             <Ville>
    				<personne nom="toto", prenom="popo">
    					<Rue1>12, avenue du développement Delphi</Rue1>
    					<Rue2 />
    					<Rue3 />
    					<Fixe>0426000000</Fixe>
    					<Fax>0426000000</Fax>
    					<Site>www.developpez.com</Site>
    				</personne>
                             </Ville>
                              <Ville>
    				<personne nom="tata", prenom="papa">
    					<Rue1>12, avenue du développement Delphi</Rue1>
    					<Rue2 />
    					<Rue3 />
    					<Fixe>0426000000</Fixe>
    					<Fax>0426000000</Fax>
    					<Site>www.developpez.com</Site>
    				</personne>
                             </Ville>
    			</Personnes>
    		</Ville> 
    	</Villes>
    </Annuaire>
    Il y a donc des balises fils portant le même nom que les pères. J'ai donc un soucis avec ça.

    Je suis donc parti là dessus :
    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
    StringBuilder output = new StringBuilder();
                    using (XmlReader reader = XmlReader.Create(new StringReader(fileContent)))
                    {
                        while (reader.ReadToFollowing("Ville"))
                        {
                            if ((reader.GetAttribute("codepostal") == "69000"))
                            {
                                do {
                                        Console.WriteLine(reader.GetAttribute("nom"));
                                    } while (reader.ReadToDescendant("personne"));
     
                            }
                            else {
                                //Console.WriteLine("not found");
                            } 
     
                        } Console.Read();
     
                    }
    Mais je n'arrive pas à récupérer les attributs des deux fils "personnes".
    Tout d'abord est ce que le reader lit les données jusqu'à la bonne balise ( ne s’arrête pas sur la balise fils portant le même nom) ?
    Et comment récupérer les noms des balises personne jusqu’à la fin de la balise parent "Ville". Car dans mon cas seul le premier enfant est récupéré.

    Merci

  6. #6
    Membre expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    octobre 2013
    Messages
    1 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2013
    Messages : 1 534
    Points : 3 428
    Points
    3 428

    Par défaut

    La dé-sérialisation a pour but de convertir ton fichier XML en objets. Tu ne devrais donc pas avoir à lire ton fichier XML comme ça. Cf l'exemple fournit par @popo..

  7. #7
    Membre chevronné
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    mars 2005
    Messages
    1 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2005
    Messages : 1 122
    Points : 1 787
    Points
    1 787

    Par défaut

    Avec mon exemple, cette structure n'est pas logique mais cela donnerai la déclaration suivante :
    Code C# : 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
    public class Annuaire
    {
        [XmlAttribute("departement")]
        public String Departement { get; set; }
     
        [XmlAttribute("annee")]
        public UInt32 Annee { get; set; }
     
        [XmlArrayItem("Ville")]
        public List<Ville> Villes = new List<Ville>();
    }
     
    public class Ville
    {
        [XmlAttribute("codepostal")]
        public String CodePostal { get; set; }
     
        [XmlAttribute("nom")]
        public String Nom { get; set; }
     
        public Personnes Personnes { get; set; }
    }
     
    public class Personnes
    {
        [XmlArrayItem("Ville")]
        public List<VilleDeLaPersonne> Personnes = new List<Personne>();
    }
     
    public class VilleDeLaPersonne
    {
        public Personne Personne { get; set; }
    }
     
    public class Personne
    {
        public String Rue1 { get; set; }
     
        public String Rue2 { get; set; }
     
        public String Rue3 { get; set; }
     
        public String Fixe { get; set; }
     
        public String Fax { get; set; }
     
        public String Site { get; set; }
    }

    Si tu me fournis ta véritable structure, je pourrai t'aider un peu mieux.

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    avril 2017
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : avril 2017
    Messages : 36
    Points : 33
    Points
    33

    Par défaut

    Bonjour,


    Voila en gros l'architecture des fichiers sur lequel je travail. Il peut y avoir plusieurs systèmes/sous-systèmes/Sous-Sous-systèmes. (environ 20.000 lignes en moyenne)
    Mon point d'entrée sera déterminé a partir de l'attribut Nom de mon SousSytem. Ensuite je travaille uniquement sur son champs (entre sa première balise Système et sa dernière). Seul les valeurs des attributs Nom m’intéressent. Comment je peux faire cela en sachant qu'il y aura d'autre balises <System> filles.

    fichier xml :
    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
     
    <?xml version="1.0" encoding="utf-8"?>
    <ModelInformation Version="0.9">
    <Model>
    <Block BlockType="SousSysteme" Nom="sousSysteme1">
       <p Nom="tag">xx</P>
       <p Nom="coordonee">xx</P>
       <Systeme>
          <p Nom="source">xx</P>
          <Block BlockType="Entree" Nom="Entree_1">
             <p Nom="coordonne"</P>
          </Block> 
          <Block BlockType="Entree" Nom="Entree_2">
             <p Nom="coordonne">xx</P>
          </Block>
          <Block BlockType="Entree" Nom="Sortie_3">
             <p Nom="coordonne">xx</P>
          </Block>
          <Block BlockType="SousSysteme" Nom="SousSysteme1.01">
             <p Nom="tag">xx</P>
             <p Nom="coordonne">xx</P>
             <Systeme>
                <p Nom="source">xx</P>
                <Block BlockType="Entree" Nom="XXX">
                   <p Nom="coordonne"</P> 
                </Block>
                <Block BlockType="Sortie" Nom="XXX">
                   <p Nom="coordonne">xx</P>
                </Block>
             </Systeme>
          </Block>
       </Systeme>
    </Block
    </Model>
    </ModelInformation>

  9. #9
    Membre chevronné
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    mars 2005
    Messages
    1 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2005
    Messages : 1 122
    Points : 1 787
    Points
    1 787

    Par défaut

    Je suis en pleine MAJ de Visual Studio alors je ne peux pas l'utiliser pour le moment mais à vu de nez la structure suivante devrait faire l'affaire :
    Code C# : 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
    public class ModelInformation
    {
    	public Model { get; set; }
    }
     
    public class Model
    {
    	public Block { get; set; }
    }
     
    public class Block
    {
    	[XmlAttribute]
    	public String BlockType { get; set; }
     
    	[XmlAttribute(AttributeName = "Nom")]
    	public String Name { get; set; }
     
    	[XmlElement(ElementName = "p")]
    	public List<Parameter> Parameters { get; set; }
     
    	public System System { get; set; }
    }
     
    public class System
    {
    	[XmlElement(ElementName = "p")]
    	public Parameter Parameter { get; set; }
     
    	[XmlElement(ElementName = "Block")]
    	public List<Block> Blocks  { get; set; }
    }
     
    public class Parameter
    {
    	[XmlAttribute(AttributeName = "Nom")]
    	public String Name { get; set; }
    }

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    avril 2017
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : avril 2017
    Messages : 36
    Points : 33
    Points
    33

    Par défaut

    Merci

    Comme je l'ai déjà dit mon fichier contient des dizaines de milliers de lignes, il y a probablement des nœuds que je ne connais pas et je n'ai pas mis tous les nœuds ( juste ceux dont j'ai besoin.
    Je peux ignorer le reste ou je dois traiter toutes les informations?

    Dans un premier temps j'aimerais pouvoir récupérer uniquement les informations/contenu html appartenant à une balise block spécifique.
    Comment faire ?

    Merci

  11. #11
    Membre chevronné
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    mars 2005
    Messages
    1 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2005
    Messages : 1 122
    Points : 1 787
    Points
    1 787

    Par défaut

    Déjà, tu utilises un XmlReader.
    Ce qui t'oblige à tester la présence d'un nœud puis à vérifier son contenu, et tout plein de contrôles qui ne vont pas simplifier les choses.

    L'exemple que je t'ai donné utilise un XmlSerializer.
    - Le XmlSerializer fera ces contrôles pour toi.
    - Le XmlSerializer fera automatiquement correspondre les nœud avec la structure de tes objets.
    Si un nœud ou un attribut est présent dans le XML mais absent de ta structure objet, il sera simplement ignoré sans générer d'erreur
    Si une propriété est présente dans ton objet mais qu'aucun nœud ou attribut n'y correspond, ça ne générera pas d'erreur et laissera simplement ta propriété sera à null.

    Ce simple code suffit à remplir automatiquement toute ton arborescence d'objet :
    ModelInformation modelInfo = null;
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    using (var stream = new StreamReader("MyXmlFile.xml"))
    {
        var serialiser = new XmlSerializer(typeof(ModelInformation));
        modelInfo = (ModelInformation)serialiser.Deserialize(stream);
    }

    Il suffit ensuite d'une requête Linq pour rechercher les informations que tu veux.

    Edit :
    Cette méthode peut prendre du temps en fonction du nombre de lignes de ton fichier. Mais 20 000 lignes devraient pouvoir être lue en relativement peu de temps.
    Tout dépend de où vont se trouver les informations que tu cherches.
    Si elles se trouvent toujours au début, ce sera sans doute moins long de lire ce fichier petit à petit mais tu auras plus de difficulté à le faire.
    Si elles sont disséminées un peu de partout ou à un emplacement aléatoire, cette méthode sera sans doute la plus rapide et la plus simple

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    avril 2017
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : avril 2017
    Messages : 36
    Points : 33
    Points
    33

    Par défaut

    Oui j'utilise maintenant XmlSerializer.

    L'exemple que je t'ai donné utilise un XmlSerializer.
    - Le XmlSerializer fera ces contrôles pour toi.
    - Le XmlSerializer fera automatiquement correspondre les nœud avec la structure de tes objets.
    Si un nœud ou un attribut est présent dans le XML mais absent de ta structure objet, il sera simplement ignoré sans générer d'erreur
    Si une propriété est présente dans ton objet mais qu'aucun nœud ou attribut n'y correspond, ça ne générera pas d'erreur et laissera simplement ta propriété sera à null.
    Super merci.

    Cette méthode peut prendre du temps en fonction du nombre de lignes de ton fichier. Mais 20 000 lignes devraient pouvoir être lue en relativement peu de temps.
    Tout dépend de où vont se trouver les informations que tu cherches.
    Si elles se trouvent toujours au début, ce sera sans doute moins long de lire ce fichier petit à petit mais tu auras plus de difficulté à le faire.
    Si elles sont disséminées un peu de partout ou à un emplacement aléatoire, cette méthode sera sans doute la plus rapide et la plus simple
    Les informations sont répartis à travers l'ensemble du fichier. Je ne connais pas les requêtes Linq. Je comptais juste récupérer les données via les attributs d'objet.

    Merci

  13. #13
    Membre chevronné
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    mars 2005
    Messages
    1 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2005
    Messages : 1 122
    Points : 1 787
    Points
    1 787

    Par défaut

    Les informations sont répartis à travers l'ensemble du fichier.
    Donc cette approche sera certainement plus efficace.

    Je comptais juste récupérer les données via les attributs d'objet.
    Avec ce mécanisme les valeurs de tes attributs sont placées dans les différentes propriétés de l'objet retourné par la méthode Deserialize.

    Je ne connais pas les requêtes Linq.
    https://docs.microsoft.com/fr-fr/dot...rted-with-linq

    Mon point d'entrée sera déterminé a partir de l'attribut Nom de mon SousSytem. Ensuite je travaille uniquement sur son champs (entre sa première balise Système et sa dernière). Seul les valeurs des attributs Nom m’intéressent.
    Tu as plusieurs entrées de type <Block BlockType="SousSysteme" Nom="sousSysteme1"> dans le nœud <Model> ?
    C'est l'impression que j'ai en lisant cette phrase et dans ce cas, il faudrait transformer la classe Model
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public class Model
    {
    	[XmlElement(ElementName = "Block")]
    	public List<Block> Blocks  { get; set; }
    }

    Et dans ce cas (j'avoue ne pas trop comprendre ce que tu veux exactement), je verrais un truc du genre :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    IEnumerable<Block> blocks = modelInfo.Model.Blocks.Where(b => b.BlockType == "SousSysteme");
    foreach (Block block in blocks)
    {
        foreach (Block sousBlock in block.System.Blocks)
        {
            String name = sousBlock.Name; // Je récupère le nom
        }
    }

    Si tu n'a qu'un seul block dans Model, c'est plus simple :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    IEnumerable<Block> blocks = modelInfo.Model.Blocks.Where(b => b.BlockType == "SousSysteme");
    foreach (Block block in modelInfo.Model.Block.System.Blocks)
    {
       String name = sousBlock.Name; // Je récupère le nom
    }

    Je ne sais pas si je m'approche de ce que tu cherches.
    Si ce n'est pas ça, il va falloir être plus précis ou me présenter les choses avec d'autres mots (ou un dessin, ou n'importe quoi qui pourrait m'aider à comprendre)

  14. #14
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    avril 2017
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : avril 2017
    Messages : 36
    Points : 33
    Points
    33

    Par défaut

    Je me suis rendu compte que je pourrais pas prévoir le niveau de profondeur des balises <Block> et <System>. Alors je ne peut pas prévoir le nombre de classe de "niveau" pour la désérialisation.

    J'ai donc totalement changé de méthodologie.
    Voici mon nouveau diagramme de classe :

    Nom : Capture.PNG
Affichages : 47
Taille : 16,4 Ko

    J'utilise XmlDocument.
    Je recherche le premier nœud <System> puis je traite touts les nœuds <Block> enfants que je souhaite.
    Si je trouve un nœud qui possède un attribut "Subsystem", alors je parcours le contenu de son enfants nœud <System> et ainsi de suite.

    Jusque là ça fonctionne cependant j'aimerais savoir si la notion de récursivité est valable aussi pour l'instanciation d'objet. Afin de me retrouver à la fin avec un objet ayant comme attributs des objets ayant comme attributs des objets etc....


    Si oui comment faire ?


    Merci

  15. #15
    Membre éclairé
    Homme Profil pro
    x
    Inscrit en
    juin 2007
    Messages
    456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : x

    Informations forums :
    Inscription : juin 2007
    Messages : 456
    Points : 686
    Points
    686

    Par défaut

    Oui, tout à fait, c'est comme ça que l'on fait les structures en arbre.

  16. #16
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    avril 2017
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : avril 2017
    Messages : 36
    Points : 33
    Points
    33

    Par défaut

    Citation Envoyé par Noxen Voir le message
    Oui, tout à fait, c'est comme ça que l'on fait les structures en arbre.
    Nickel.

    Avant de passer à cette étape j'aimerais déjà pouvoir parcourir tous mon fichier xml. Je ne sais pas comment remonter au niveau du nœud parent et ensuite continuer la recherche à partir du nœud suivant de ce parent. (afin d’éviter une boucle et de passer à la "branche suivante").

    Voici une représentation de l'architecture générale corrigé de mon xml (le niveau de profondeur Système/SousSystème est variable) :

    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
    <?xml version="1.0" encoding="utf-8"?>
    <ModelInformation Version="0.9">
       <Model>
          <System Name ="ici">
             <Block BlockType="SubSystem" Name="subSysteme1">
                <P Name="tag">xx</P>
                <P Name="Position">xx</P>
                <System>
                   <P Name="source">xx</P>
                   <Block BlockType="Inport" Name="Entree_1">
                      <P Name="Position"></P>
                   </Block> 
                   <Block BlockType="Inport" Name="Entree_2">
                      <P Name="Position">xx</P>
                   </Block>
                   <Block BlockType="Inport" Name="Sortie_3">
                      <P Name="Position">xx</P>
                   </Block>
                   <Block BlockType="SubSystem" Name="SubSysteme1.01">
                      <P Name="tag">xx</P>
                      <P Name="Position">xx</P>
                      <System>
                         <P Name="source">xx</P>
                         <Block BlockType="Inport" Name="XXX">
                            <P Name="Position"></P> 
                         </Block>
                         <Block BlockType="Sortie" Name="XXX">
                            <P Name="Position">xx</P>
                         </Block>
                      </System>
                   </Block>
                </System>
             </Block>
          </System>
       </Model>
       <Grapic>
          <P/>
          <P/>  
       </Grapic>   
    </ModelInformation>
    Voici ma fonction récursive :

    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
    private static int node_count = 0;
            private static bool node_following = false;
            private static void TraverseNodes(XmlNode node)
            {  
     
     
                    foreach (XmlNode child_node in node.ChildNodes)
                    {
                        if()// get next child_node folowing with bool node_following
                        {
                            // que faire ici pour repartir depuis le noeud suivant 
                        }
                        //Console.WriteLine("ici");
                        try
                        {
                            if (child_node.Name == "System")
                            {
                                //XmlNodeList childs_node = node.ChildNodes;
                                foreach (XmlNode block_node in child_node.ChildNodes)
                                {
                                    if (block_node.Name == "Block") // get All <Block> node  to have Inport,Outport,TriggerPorte,Susbystem
                                    {
     
                                        switch (block_node.Attributes["BlockType"].Value)
                                        {
                                            case ("Inport"):
                                                Console.WriteLine(block_node.Attributes["BlockType"]);
                                                //system.inport.Add(node.Attributes["Name"].Value);
                                                break;
                                            case ("Outport"):
                                                //system.outport.Add(node.Attributes["Name"].Value);
                                                break;
                                            case ("TriggerPort"):
                                                //system.triggerport.Add(node.Attributes["Name"].Value);
                                                break;
                                            case ("SubSystem"):
                                                //system.subsystem.Add(node.Attributes["Name"].Value);
                                                Console.WriteLine("here");
                                                node_count++;
                                                TraverseNodes(block_node); // get subsytem of subsystem
                                                break;
                                            default:
                                                break;
                                        }
     
                                    }
                                }
     
                            }
     
                            else if (child_node.HasChildNodes)  // if no <System> node among them
                            {
                                node_count++;
                                TraverseNodes(child_node);
                            }
                            else if (!child_node.HasChildNodes)
                            {
                                node_following = true;
                                TraverseNodes(node.ParentNode);//search neighbor node
                            }
     
                        }
     
                        catch (Exception ex)
                        {
                            MessageBox.Show("Error in reading XML", "xmlError", MessageBoxButtons.OK);
                        }
     
                }         
            }

Discussions similaires

  1. problème pour parser un fichier xml avec XML::Simple
    Par black_code dans le forum Modules
    Réponses: 3
    Dernier message: 30/01/2006, 19h32
  2. [xslt] Parser 2 fichiers XML
    Par malekms dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 30/12/2005, 12h22
  3. Parser un fichier XML
    Par Charlinecha dans le forum XML
    Réponses: 1
    Dernier message: 11/07/2005, 17h18
  4. [SAX] parser un fichier xml en Java
    Par royou dans le forum XML
    Réponses: 1
    Dernier message: 10/02/2005, 17h12
  5. parser des fichier .xml en perl
    Par djibril dans le forum Modules
    Réponses: 13
    Dernier message: 18/05/2004, 17h08

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