Parcours d'un hash de données XML

Parcours d'un hash de données XML - Perl - Programmation

Marsh Posté le 16-11-2005 à 10:03:02    

Bonjour,
j'ai un fichier contenant des données XML, ce fichier est en fait un filtre pour des données récupérées d'une base de données. Donc pour pouvoir parser ce document j'utilise la librairie XML::Simple.  
 
#Lecture du fichier
my $data = $xml->XMLin($file); // je récupère les données du fichier
 
J'ai donc un arbre des informations.
Seulement j'aimerai pouvoir récupérer mes informations un peu comme dans un tableau simple, genre :
 
$data[$i];//Si j'utilisai une boucle for
 
Malheureusement, je n'arrive pas à réaliser cela, de même si je veux savoir le nombre d'informations contenues dans $data je n'y arrive pas, même avec keys ou scalar. J'ai bien fait ref($data), qui me donne "HASH". Mais je n'arrive pas à l'utiliser correctement ce soi disant "HASH". Si vous pouviez m'aider à parcourir $data dans une boucle, j'ai essayé de le faire avec :
 
foreach my $e (@{$data}){...}
 
 Mais ça ne marche pas, il me dit qu'il y a un problème au niveau Array et Hash de $data justement. Merci de votre aide.

Reply

Marsh Posté le 16-11-2005 à 10:03:02   

Reply

Marsh Posté le 16-11-2005 à 10:19:56    

Euh... J'ajoute que j'aimerai que ça soit récursif, dans le genre :  
Tant que je ne suis pas arrivé à la fin de ma balise, si ma balise contient une autre balise je me base sur cette dernière...
 
Je ne sais pas si je suis très clair là...

Reply

Marsh Posté le 16-11-2005 à 10:31:54    

neo00neo a écrit :

Bonjour,
...
Malheureusement, je n'arrive pas à réaliser cela, de même si je veux savoir le nombre d'informations contenues dans $data je n'y arrive pas, même avec keys ou scalar.  
...


 
Qu'est ce que tu entends par le nombre d'information???
 
Normalement, XML::Simple te retourne une reference sur tableau pour les elements imbriqués et une reference sur une hash pour les attributs. Comme te le prouve l'exemple de la CPAN:

Code :
  1. <opt>
  2.       <person firstname="Joe" lastname="Smith">
  3.         <email>joe@smith.com</email>
  4.         <email>jsmith@yahoo.com</email>
  5.       </person>
  6.       <person firstname="Bob" lastname="Smith">
  7.         <email>bob@smith.com</email>
  8.       </person>
  9.     </opt>
  10.     {
  11.       'person' => [
  12.                     {
  13.                       'email' => [
  14.                                    'joe@smith.com',
  15.                                    'jsmith@yahoo.com'
  16.                                  ],
  17.                       'firstname' => 'Joe',
  18.                       'lastname' => 'Smith'
  19.                     },
  20.                     {
  21.                       'email' => 'bob@smith.com',
  22.                       'firstname' => 'Bob',
  23.                       'lastname' => 'Smith'
  24.                     }
  25.                   ]
  26.     }


 
tu pourrais nous montrer ce que sort le dumper de ton $ref?

Reply

Marsh Posté le 16-11-2005 à 10:45:05    

Voilà ce que me donne : print Dmper($data);
 
$VAR1 = {  
'condition' => {
   'element' => [ {  
      'valeur' => '10', 'attribut' => 'nature', 'op' => '>=' },
                       {
      'valeur' => '2', 'attribut' => 'etat', 'op' => '!=' } ],
'type' => 'ET' } };
 
Voici mon fichier XML :
<filtre>
 <condition type="ET">
  <element attribut="nature" op=">=" valeur="10" />
  <element attribut="etat" op="!=" valeur="2" />
 </condition>
</filtre>
 
 
Sachant que la récursivité me permettait de savoir si j'ai des balises <condition...>, et le cas échéant aller regarder ce qu'il y a dedans. Voilà, merci de ton aide !

Reply

Marsh Posté le 16-11-2005 à 15:21:37    

Bon je n'arrive pas à faire la récursivité, ni à recherche un élément... Si quelqu'un peut m'aider, n'hésitez pas ;-), merci.

Reply

Marsh Posté le 16-11-2005 à 15:29:31    

LAisse tomber XML-Simple et prend XML-Twig

Reply

Marsh Posté le 16-11-2005 à 20:09:51    

Code :
  1. my $data = $xml->XMLin($file);
  2. if ($data->{ condition })
  3. {
  4.     my $element;
  5.     print "type = ".$data->{ condition }->{ type }."\n";
  6.     foreach $element (@{$data->{ condition }->{ element }})
  7.     {
  8.          print "valeur = ".$element->{ valeur }."\n";
  9.          print "attribut = ".$element->{ attribut }."\n";
  10.          print "op = ".$element->{ op }."\n";
  11.     }
  12. }


 
bout de code à vérifier, je viens de le pondre sans aucun vérif.
 
maintenant ce qu'il faut savoir, c'est que si tu as plusieurs fois la balises <condition> XML-Simple va te créer un tableau de hash. Dans ton exemple, comme tu n'as qu'une seule fois la balise <condition> c'est tout simplement un hash
Tu peux forcer la création de tableaux même si il n'y a qu'un seul élément avec les options de XML-Simple, dans ce cas là ta boucle pour récupérer les infos sera tjs la même
à voir sur http://search.cpan.org/~grantm/XML [...] /Simple.pm
 
Exemple :

Code :
  1. my $data = $xml->XMLin($file, ForceArray => [ 'condition' ]);


Dans ce cas là ton code deviendra (à vérifier !) :

Code :
  1. my $condition;
  2. foreach $condition (@{$data->{ condition }})
  3. {
  4.     my $element;
  5.     print "type = ".$condition->{ type }."\n";
  6.     foreach $element (@{$condition->{ element }})
  7.     {
  8.          print "valeur = ".$element->{ valeur }."\n";
  9.          print "attribut = ".$element->{ attribut }."\n";
  10.          print "op = ".$element->{ op }."\n";
  11.     }
  12. }

Reply

Marsh Posté le 17-11-2005 à 10:02:30    

J'ai recopié ton code couak, je te remercie d'ailleurs, et il me met une erreur :
[Thu Nov 17 10:03:44 2005] SUPERVISIONalertes.pl: Unrecognised option: ForceArray at SUPERVISIONLireXMLe.pl line 71
 
Donc je ne comprends pas pourquoi, voici ma ligne :
 my $data = $xml->XMLin($file,ForceArray => ['condition']);
 
Je ne vois pas pourquoi ça ne marche pas... Surement que je n'ai pas la bonne version.
J'ai fait des modifications pour prendre en compte soit avoir un tableau soit un élément seul, donc ce point est résolu, mais ta solution ne prend pas encompte si par exemple j'ai comme fichier XML :
<filtre>
 <condition type="ET">
  <element attribut="nature" op=">=" valeur="10" />
  <condition type="TEST">
  </condition>
  <element attribut="etat" op="!=" valeur="20" />
  <condition type="OU">
   <element attribut="nature" op=">=" valeur="30" />
   <condition type="TEST2">
    <condition type="TEST3">
     <element attribut="nature" op=">=" valeur="40" />
     <element attribut="nature" op=">=" valeur="50" />
    </condition>
   </condition>
  </condition>
 </condition>
</filtre>
 
C'est à dire avec plusieurs <condition> imbriquées. Merci de ton aide.


Message édité par neo00neo le 17-11-2005 à 10:21:27
Reply

Marsh Posté le 17-11-2005 à 11:48:59    

maintenant que tu sais comment marche XML-Simple et les structures de données, tu vas nous pondre un gentil code et nous soumettre tes problèmes au lieu d'attendre que je te fasse ton boulot :)

Reply

Marsh Posté le 17-11-2005 à 12:49:44    

C'est cool, pas de problème.
OK, merci ! ;-)


Message édité par neo00neo le 17-11-2005 à 13:00:31
Reply

Sujets relatifs:

Leave a Replay

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