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

wxWidgets Discussion :

Parser un fichier XML


Sujet :

wxWidgets

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut Parser un fichier XML
    Bonjour,

    Comme l'indique le titre, je souhaite parser un fichier XML. Plus précisément, je voudrais charger un fichier XML, le parcourir pour extraire les données qu'il contient, puis afficher le texte contenant les informations à l'écran.

    Le problème est que je ne connait quasiment pas les "normes" du XML, à part que c'est un lange de balises, j'ai donc besoin d'un peu d'aide pour parser le fichier. Je sais déja qu'il y a 3 classes à utiliser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    XML classes
     
    wxXmlDocument 	A class to parse XML files.
    wxXmlNode 	A class which represents XML nodes.
    wxXmlProperty 	A class which represents XML properties.
    Je vous donne un exemple de mes fichiers XML à traiter, il s'agit d'extraire plusieurs informations :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <element tag="0002,0000" vr="UL" vm="1" len="4" name="MetaElementGroupLength">194</element>
    Je voudrais extraire les champs tag, vr, vm, len, name ainsi que la valeur de l'élément (194 ici).

    Un conseil sur la manière de procéder ?
    Merci. A+.

    Edit : toutes les infos à récupérer sont présentées de la même manière que l'exemple fourni. <element ....... </element>

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Commençons par le vocabulaire XML :
    Un fichier XML :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <?xml version="1.0" encoding="utf-8"?>
    <premier>
      <element attribut1="valeur" attribut2="2">
        texte
        <sous_element>sous texte</sous_element>
        encore du texte
        <autre_sous_element autre_attribut="autre valeur">autre sous texte</autre_sous_element>
         toujours du texte !
      </element>
    </premier>
    La première ligne indique qu'il s'agit d'un fichier XML, que la version XML est 1.0 et que l'encodage du fichier est en utf-8. Tout les documents XML commencent par une ligne de ce genre.
    Pour faire simple, tu peux voir un fichier XML comme un arbre (wxTreeCtrl).
    Chaque chose d'un fichier XML est un noeud de l'arbre. On distingue trois type de noeuds :
    -> Les noeuds balises : <balise>
    -> Les noeuds attributs : <balise attribut="valeur">
    -> Les noeuds contenus : <balise> contenu </balise>

    Un noeud balise est constitué de : un nom, la liste de ses noeuds attributs et la liste de ses noeuds fils. Les noeuds fils sont soit des noeuds balises soit des noeuds contenu. Ce sont tous ce qui se trouve entre <balise> et </balise> :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      <element attribut1="valeur" attribut2="2">
        texte
        <sous_element>sous texte</sous_element>
        encore du texte
        <autre_sous_element autre_attribut="autre valeur">autre sous texte</autre_sous_element>
         toujours du texte !
      </element>
    Cela nous donne :
    -> nom = élément
    -> Attributs = ( (attribut1, "valeur"), (attribut2,"2"))
    -> Fils = (texte, sous_element,encore du texte, autre_sous_element, toujours du texte !)

    Un noeud attributs est constitué d'un nom et d'une valeur.
    Dans l'exemple ci-dessus : (attribut1, "valeur") et (attribut2,"2") sont des noeuds attributs

    Un noeud contenu est constitué d'un ... contenu c'est à dire du texte sans balises. Dans l'exemple ci-dessus "encore du texte" est un noeud texte.

    Tout document XML valide contient au moins un noeud balise : la racine. D'ailleurs, ce noeud racine ne peut pas avoir de 'frère', c'est à dire de noeud de même niveau que lui. Tous les autres noeuds du documents doivent être des fils du noeud racine.

    Comment est modélisé tout ça dans wxWidget :
    wxDocument est ton document : tu peux voir ça comme ton fichier.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    wxDocument mon_doc;
    if(!mon_doc.Load(wxT("monFichier.xml"))){
      // erreur
    }
    On obtient l'encodage du fichier avec GetFileEncoding :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    wxMessageDialog dlg_enc(this,mon_doc.GetFileEncoding());
    dlg_enc.ShowModal();
    Les noeuds balises et les noeuds contenus sont des instances de la classe wxXmlNode. On obtient le noeud racine à partir du document :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    wxXmlNode *p_noeud_racine(mon_doc.GetRoot());
    On a dit qu'un noeud balise est constitué d'un nom, d'une liste de noeuds attributs et d'une liste de noeuds fils.

    Le nom s'obtient avec : wxXmlNode::GetName.
    Avec notre exemple, pour le noeud racine, GetName retourne "premier".

    Les attributs sont des instances de wxXmlProperty. On les obtiens avec wxXmlNode::GetProperties :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    wxXmlProperty *p_attributs(p_noeud->GetProperties());
    Le nom d'un attribut est : wxXmlProperty::GetName
    La valeur d'un attribut est : wxXmlProperty::GetValue
    Attention wxXmlNode::GetProperties ne retourne pas un tableau ou je ne sais quoi d'autre. On ne sait pas comment sont enchaînés les attributs. Pour passer à l'attribut suivant, on utilise wxXmlProperty::GetNext. Il n'y a plus d'attribut quand wxXmlProperty::GetNext retourne NULL.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void ListerAttributs(wxXmlNode*p_noeud_)
    {
       wxLogMessage(wxT("%s a comme attributs : "),p_noeud_->GetName());
       wxXmlProperty*p_attribut(p_noeud_->GetProperties ());
       while(p_attribut)
       {
          wxLogMessage(wxT("-> %s = %s "),p_attribut->GetName(), p_attribut->GetValue());
          p_attribut = p_attribut->GetNext();
       }
    }
    Les fils sont des instances de wxXmlNode. On obtient le premier avec wxXmlNode::GetChildren. Comme pour les attributs, les suivants s'obtiennent avec wxXmlNode::GetNext :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void ListerFils(wxXmlNode*p_noeud_)
    {
       wxLogMessage(wxT("%s a comme fils : "),p_noeud_->GetName());
       wxXmlNoeud *p_fils(p_noeud_->GetChildren());
       while(p_fils)
       {
          wxLogMessage(wxT("-> %s "),p_fils->GetName());
          p_fils = p_fils->GetNext();
       }
    }
    Les noeuds contenus sont aussi des wxXmlNode sauf que :
    -> GetName() renvoie 'text'
    -> GetProperties renvoie NULL
    -> GetChildren renvoie NULL.
    On obtient le texte avec wxXmlNode::GetContent.
    wxXmlNode::GetContent pour un noeud balise renvoie une chaîne vide.

    On peut différencier les types de noeuds avec wxXmlNode::GetType
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if(p_noeud->GetType()==wxXML_TEXT_NODE){
    //...
    }
    else
    if(p_noeud->GetType()==wxXML_ATTRIBUTE_NODE){
    //...
    }
    Enfin, pour un noeud balise qui ne contient qu'un seul fils de type noeud contenu, on peut directement obtenir celui-ci avec wxXmlNode::GetNodeContent.

    J'espère que cela t'éclaircit un peu...

    Pour répondre brutalement à ta question :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <element tag="0002,0000" vr="UL" vm="1" len="4" name="MetaElementGroupLength">194</element>
    (1)element : wxXmlNode (GetName=="element")
    (2)tag="0002,0000" : wxXmlProperty (GetName()=="tag", GetValue()=="0002,0000", GetNext() renvoi sur vr)
    (3) GetChildren sur (1) renvoi un wxXmlNode avec GetContent()==194 et GetNext()==NULL

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    J'ai oublié de rajouter que tu as besoin de lier ton projet avec : wxbase28_xml ETwxexpat

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut
    Franchement 3DArchi merci beaucoup d'avoir pris le temps de m'expliquer toutes ces choses qui sont d'ailleurs fortement intéressantes, que ce soir pour le développement ou la compréhension du XML.

    C'est clair, précis, illustré et largement assez complet pour mes besoins.

    J'ai maintenant tous les outils en main, je te tient au courant si il y a des points à éclaircir ou des problèmes.

    Merci encore

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut
    Sinon, ya-t-il une méthode simple pour parcourir tous les noeuds du fichier XML. Sachant que c'est comme un arbre, peut-être un bon vieux parcours en profondeur ?

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Je n'en connais pas. La récursivité se prête assez bien pour ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    wxXmlDocument document;
    document.Load(...);
    AnalyserNoeud(document.GetRoot());
    et
    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
     
    ... AnalyserNoeud(wxXmlNode *p_noeud_,...)
    {
       if(!p_noeud_){
          // parcours terminé.
          return ;
       }
       // analyse en profondeur : on commence par les fils :
       AnalyserNoeud(p_noeud_->GetChildren());
       // le noeud courant :
       p_noeud_->GetName(); // nom du noeud
       p_noeud_->GetContent();// contenu du noeud
       // analyse des attributs : 
       wxXmlProperty * attributs_noeud(p_noeud_->GetProperties());
       while(attributs_noeud){
          // nom de l'attribut
          attributs_noeud->GetName();
          // nom de la valeur
          attributs_noeud->GetValue();
          // au suivant !
          attributs_noeud = attributs_noeud->GetNext();
       }
       // les frères : 
       AnalyserNoeud(p_noeud_->GetNext(),p_treectrl_,parent_id_);
    }
    pour une analyse en largeur :
    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
     
    ... AnalyserNoeud(wxXmlNode *p_noeud_,...)
       if(!p_noeud_){
          // parcours terminé.
          return ;
       }
       // on commence par le noeud courant 
       p_noeud_->GetName(); // nom du noeud
       p_noeud_->GetContent();// contenu du noeud
       // analyse des attributs : 
       wxXmlProperty * attributs_noeud(p_noeud_->GetProperties());
       while(attributs_noeud){
          // nom de l'attribut
          attributs_noeud->GetName();
          // nom de la valeur
          attributs_noeud->GetValue();
          // au suivant !
          attributs_noeud = attributs_noeud->GetNext();
       }
       // puis les frères : 
       AnalyserNoeud(p_noeud_->GetNext(),p_treectrl_,parent_id_);
       // les fils :
       AnalyserNoeud(p_noeud_->GetChildren());

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut
    Oui, c'est ce dont je parlais, c'est à dire que pour le parcours d'arbre il y a 2 grandes sortes de parcours : en largeur et en profondeur.

    Je pense qu'on a bien fait le tour de la question, je passe en résolu.

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut
    Oui, je croyais l'avoir fait, c'est bon ^^

+ Répondre à la discussion
Cette discussion est résolue.

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 Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 11/07/2005, 17h18
  4. [SAX] parser un fichier xml en Java
    Par royou dans le forum Format d'échange (XML, JSON...)
    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