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

Modules Perl Discussion :

Perl et attribut xml : Twig ?


Sujet :

Modules Perl

  1. #21
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    Bonsoir cmcmc,

    Je ne sais pas qui a voté négativement à ton message, mais bon, on s'en...
    Pour revenir à ton message, je ne dis pas que tes regex sont mauvaises, loin de là, mais ce n'est pas une bonne habitude à donner aux débutants. Ce qui ne le sont pas de toute façon ont surement soit fait une regex qui fonctionne dans leur code, soit utilisé un parseur.
    Par expérience sur ce forum depuis de nombreuses années, les questions sur les fichiers XML débutent toujours par la récupération de données assez basiques, puis on bifurque rapidement sur d'autres données, sur des fichiers plus gros et plus complexes. Donc autant proposer les meilleurs parseurs XML existants.

  2. #22
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    kenobiwan88,

    Je sais que lorsque l'on débute, ce n'est pas toujours évident de demander clairement ce que l'on souhaite car on ne connais pas les rouages du langage, néanmoins, il est important de d'expliquer clairement ce que l'on souhaite faire avec un fichier et de montrer ce que l'on souhaite avoir comme résultat.

    Récupérer telle ou telle donnée n'est en soi pas compliquée, mais en fonction de ta problématique, nous pouvons t'orienter sur une solution ou une autre.
    Parser un fichier XML peut se faire en chunck by chunk, mais il est aussi possible de mettre tout en mémoire. Tout dépend de ta problématique, mais pour cela, faut nous dire ce que tu souhaites vraiment faire.

  3. #23
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par djibril Voir le message
    Bosoir cmcmc,

    Je ne sais pas qui a voté négativement à ton message, mais bon, on s'en...
    Toi peut-être. J'aimerais comprendre.

    Pour revenir à ton message, je ne dis pas que tes regex sont mauvaises, loin de là, mais ce n'est pas une bonne habitude à donner aux débutants. Ce qui ne le sont pas de toute façon ont surement soit fait une regex qui fonctionne dans leur code, soit utilisé un parseur.
    Par expérience sur ce forum depuis de nombreuses années, les questions sur les fichiers XML débutent toujours par la récupération de données assez basiques, puis on bifurque rapidement sur d'autres données, sur des fichiers plus gros et plus complexes. Donc autant proposer les meilleurs parseurs XML existants.
    Peut-être. Je me retrouve pour ma part à devoir traiter des gigaoctets de données en format XML trivial parce qu'à un moment donné un âne bâté (ou son boss) a jugé que c'était plus sexy de produire du XML qu'un CSV. Résultat : volumes multipliés par un facteur compris entre 3 et 10 selon l'imagination du gugusse en charge du nommage des entités et des attributs, avec les impacts qu'on imagine sur la bande passante et l'espace disque. A mon niveau et sur ces fichiers l'utilisation d'expressions régulières permet au moins de minimiser l'utilisation CPU des traitements dont j'ai la responsabilité.

    Mais j'entends ce que tu dis et en tiendrai compte.
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  4. #24
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    Citation Envoyé par cmcmc Voir le message
    Peut-être. Je me retrouve pour ma part à devoir traiter des gigaoctets de données en format XML trivial parce qu'à un moment donné un âne bâté (ou son boss) a jugé que c'était plus sexy de produire du XML qu'un CSV. Résultat : volumes multipliés par un facteur compris entre 3 et 10 selon l'imagination du gugusse en charge du nommage des entités et des attributs, avec les impacts qu'on imagine sur la bande passante et l'espace disque. A mon niveau et sur ces fichiers l'utilisation d'expressions régulières permet au moins de minimiser l'utilisation CPU des traitements dont j'ai la responsabilité.

    Mais j'entends ce que tu dis et en tiendrai compte.
    L'avantage du XML est sa complexité car on peut tout y mettre. Son inconvénient est que l'on peut tout de suite avoir des fichiers de tailles très importantes. Néanmoins, les meilleurs parseurs dont XML::Twig permettent de les analyser sans aucun souci de mémoire car on ne les mets pas en mémoire, uniquement les parties que l'on souhaite, d'où l'avantage des twig_handler. Le module est déjà optimisé donc les regex transparentes pour nous font déjà le job correctement. XML::LibXML fait également le job, est très rapide car écrit en C. Pour ces deux modules, la seule difficulté est de bien les utiliser et ensuite, on ne se souci plus de l'indentation du fichier...

  5. #25
    Membre à l'essai
    Homme Profil pro
    Débutant !!
    Inscrit en
    Novembre 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Débutant !!
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2015
    Messages : 29
    Points : 19
    Points
    19
    Par défaut
    Bonsoir,

    je suis navré d'avoir déclencher la polémique (pour la partie technique, je comprends pas grand chose de vos échanges ).

    Quoi qu'il en soit, je remercie INFINIMENT cmcmc qui a permis de finaliser la partie 1 de mon projet en une petite journée !!!

    J'ai donc un code (presque) fonctionnel.
    Pour Djibril, mes excuses j'aurai du commencer à présenter mon projet. Je le fais désormais : le script permet, en rentrant une des adresses de la société livetrail qui assure le chronométrage sur des évenements sportifs, ainsi qu'un numéro de dossard, d'avoir un suivi point par point d'un coureur au choix.

    il ne me reste plus qu'à travailler sur l'envoi par mail automatique du contenu du fichier texte de résultat.

    Enfin, pendant ces épreuves, je mettrai en place un schtasks toutes les x minutes, afin de recevoir un mail régulier avec l'état d'avancement par heure (si la personne a été pointée).

    Voila mon code (presque) finalisé :

    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
    use strict;
    use warnings;
    use strict;
    use XML::Twig;
    use utf8;
    use LWP::UserAgent; 
    use LWP::Simple;
    use Data::Dumper;
     
     
    my $urlbase="http://utmb.livetrail.net/coureur.php"; #choix de l'url de la course livetrail 
    my $dossardsuivi="8"; #numéro de dossard impératif
     
    my $url=$urlbase."?rech=".$dossardsuivi; #création de l'adresse php complète d'accès au suivi
    getstore($url, 'suivilive.xml') or die 'Unable to get page'; #récupération des données html et enregistrement
     
    # Création du fichier résultat
    my $FichierResulat = 'resultat.txt';
    open( my $FhResultat, '>', $FichierResulat )
      or die("Impossible d'ouvrir le fichier $FichierResulat\n$!");
     
     #routine cmcmc
    my ($filename) = 'suivilive.xml';
     
    {
        my $c;
     
        XML::Twig->new(
    	twig_handlers => {
    	    map { my ($name, $id, $wanted) = @$_; 
    		  my @wanted_atts = @$wanted;
    		  $name => sub { my ($t, $e) = @_;
    				 my %h = map { $_ => $e->att($_)} @wanted_atts;
    				 if ($id) {
    				     $c->{$name}{$h{$id}} = \%h;
    				 } else {
    				     push @{$c->{$name}}, \%h;
    				 }
    		  } }
    	    ['identite', undef, [qw(nom prenom sx)]],
    	    ['e', 'idpt', [qw(idpt clt tps hd jd hd)]],
    	    ['pt', 'idpt', [qw(idpt km n d)]]
    	}) ->parsefile($filename);
     
    	print {$FhResultat} "Bienvenu sur le suivi live de $c->{identite}[0]{prenom} $c->{identite}[0]{nom}\n" ;
        print {$FhResultat} "Depart de $c->{pt}{0}{n} : $c->{e}{0}{hd}\n" ;
    	print {$FhResultat} ("======================================\n\n");
     
    	#routine cmcmc trop complexe pour moi
     
        #for (sort { $a <=> $b } keys %{$c->{e}}) {
    	#next unless $_; 
    	#my ($idpt, $clt, $ha) = @{$c->{e}{$_}}{qw(idpt clt ha)};
    	#print "$c->{identite}[0]{prenom} est arrivee a $c->{pt}{$idpt}{n} :  $ha - Classement : $clt\n";
        #}
     
    	#affiche des résultats à chaque point de passage
    	foreach my $keys (sort {$a <=> $b} keys %{$c->{e}})  {
    	if ($keys!=0){
    print {$FhResultat} "\n $c->{identite}[0]{prenom} est arrivee a $c->{pt}{$keys}{n} en $c->{e}{$keys}{clt}e position\n";
    print {$FhResultat} "Distance parcourue : $c->{pt}{$keys}{km} km\nAscension : $c->{pt}{$keys}{d} m+\nChrono : $c->{e}{$keys}{tps}\n";
    print {$FhResultat} ("---------------------------------------------------------------------------");
    }
    }
     
    print("Fichier resultat.txt ok");	
     
     
    	}
    Cependant cmcmc :
    - j'ai toujours le type d'erreur que je t'ai signalé précémment
    use of uninitialized value $h{'idpt"} in hash element at C:\...\livetrail.pl line 35
    - et surtout, jai certains points de passage où le classement et le chrono ne s'affiche pasdans resultat.txt (Vallorcine par exemple). avez vous la même chose ? l'erreur console est la suivante sur les différents points où il manque des infos :
    use of uninitialized value in concatenation (.) or string at C:\...\livetrail.pl line 60
    ... ou 61 d'ailleurs.

    Pour ce dernier point, cela semble provenir de la forme même du xml, et notamment des balises <e> ou <pt> qui sont toutes les unes à la suite des autres sans retour à la ligne. J'ai fait un mini test rapide en faisant "entrée" entre chaque balise <pt>, cela avait l'air de mieux se comporter. De la à dire que je vois comment faire pour automatiser cette lecture propre ...

    Encore merci pour votre aide et pour les cours et tutoriels Perl. Bonne soirée

  6. #26
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par kenobiwan88 Voir le message
    - j'ai toujours le type d'erreur que je t'ai signalé précémment

    - et surtout, jai certains points de passage où le classement et le chrono ne s'affiche pasdans resultat.txt (Vallorcine par exemple). avez vous la même chose ? l'erreur console est la suivante sur les différents points où il manque des infos :
    ... ou 61 d'ailleurs.
    Avec le fichier xml complet, tout s'éclaire

    Le problème vient du fait qu'il y a plusieurs entités nommées e dans le fichier. On a des <pass> <e ... /> ... </pass> mais aussi des <videos> <e ... /> ... </videos>, etc.
    Or, notre programme sous sa forme actuelle détecte toutes les entités de type e.

    Les entités e qui nous intéressent sont celles qui sont enfants de <pass>.

    La modification ci-dessous permet de le faire. On change légèrement la spécification du générateur de handlers:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ['pass/e',   'e',   'idpt', [qw(idpt clt tps hd jd hd)]],
    • Le premier champ ('pass/e') est maintenant un chemin dans l'arbre xml : ici pass/e signifie qu'on veut les entités de nom e qui sont enfants d'un pass.
    • Le second champ (ici 'e') est le nom sous lequel on veut la retrouver dans $c. Si undef, on prend la valeur du premier champ. Ici j'ai repris e pour ne rien avoir à changer dans le reste du programme, mais on pourrait prendre 'passage' par exemple, sous réserve de changer toutes les occurrences ultérieures de $c->{e} en $c->{passage}. On aurait pu mettre undef également, mais là il fallait changer $c->{e} en $c->{'pass/e'} ce qui est un peu pénible.
    • Le troisième champ indique comme avant la clé à utiliser si on représente l'ensemble des entités via un hash
    • Le quatrième champ est également inchangé, il donne la liste des attributs à collecter


    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
        XML::Twig->new(
    	twig_handlers => {
    	    map { my ($path, $name, $id, $wanted) = @$_; 
    		  $name = $path unless defined($name);
    		  my @wanted_atts = @$wanted;
    		  $path => sub { my ($t, $e) = @_; 
    				 my %h = map { $_ => $e->att($_)} @wanted_atts;
    				 if ($id) {
    				     die "erreur de modélisation : il y a plusieurs entités de type $path et de nom $name pour la clé $h{id}"
    					 if exists $c->{$name}{$h{$id}};
    				     $c->{$name}{$h{$id}} = \%h;
    				 } else {
    				     push @{$c->{$name}}, \%h;
    				 }
    		  } }
    	    ['identite', undef, undef,  [qw(nom prenom sx)]],
    	    ['pass/e',   'e',   'idpt', [qw(idpt clt tps hd jd hd)]],
    	    ['pt',       undef, 'idpt', [qw(idpt km n d)]]
    	}) ->parsefile($filename);
    Moyennant cette modif (le reste du code est inchangé), le programme tourne sans warnings chez moi et les chronos semblent crédibles (je te laisse vérifier...)
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  7. #27
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Autre point, autant il est logique de construire un hashref pour accéder aux pt via leur idpt, autant en fait ça a moins de sens pour les pass/e.

    Là en fait on fait confiance au développeur du schema de données, mais bon, il n'est pas déraisonnable de penser que idpt soit un identifier unique pour chaque pt, i.e. une clé primaire sur les pt.

    Dans les pass/e, idpt est clairement une clé étrangère sur les pt. Il semble que ce soit également une clé primaire pour les pass/e mais ce n'est pas particulièrement utile. Pour les besoins de cette application il est suffisant de considérer l'ensemble des pass/e comme une liste et non comme un hash.

    Je te recommande donc de changer la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	    ['pass/e',   'e',   'idpt', [qw(idpt clt tps hd jd hd)]],
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	    ['pass/e',   'e',   undef,  [qw(idpt clt tps hd jd hd)]],
    et d'adapter en conséquence ton code d'impression. Le point de départ devient $c->{e}[0] au lieu de $c->{e}{0}, et tu peux boucler sur les points de passage par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for my $e (@{$c->{e}}) { 
      next unless $e->{idpt}; # point de départ
      ... # on accède par exemple au chrono par $e->{tps}
    }
    Ce n'est pas indispensable mais je trouve ça plus propre
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  8. #28
    Membre à l'essai
    Homme Profil pro
    Débutant !!
    Inscrit en
    Novembre 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Débutant !!
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2015
    Messages : 29
    Points : 19
    Points
    19
    Par défaut
    Bonsoir cmcmc

    Merci pour ces ultimes précisions.
    Je tiens à t'exprimer toute ma gratitude pour l'aide que tu m'as apporté.

    Mon projet est donc terminé.

    J'ai mis en place l'envoi du contenu des résultats par mail et suis OK sur le schtasks lanceur pour être tenu informé à la fréquence désirée !

    (Le même service par le site web coûte 5€ par dossard... Il présente simplement l'avantage d'envoyer une mise à jour juste après le passage à un nouveau point)

    Encore merci à toi !

  9. #29
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par kenobiwan88 Voir le message
    Mon projet est donc terminé.
    Bien ouéj

    N'oublie pas que seul toi peut marquer cette discussion comme résolue.

    J'imagine que ce n'est pas une priorité pour toi à ce stade mais ce serait bien que tu comprennes le fonctionnement du générateur de handlers, à savoir la partie ... dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        XML::Twig->new(
    	twig_handlers => {
    	    ...
    	}) ->parsefile($filename);
    Si tu trouves le temps de t'y intéresser n'hésite pas à revenir poser des questions sur ce fil ou ailleurs. Il y a là quelques trucs pas tout à fait évidents à discuter si ça te dit.

    Bonne continuation
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  10. #30
    Membre à l'essai
    Homme Profil pro
    Débutant !!
    Inscrit en
    Novembre 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Débutant !!
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2015
    Messages : 29
    Points : 19
    Points
    19
    Par défaut
    Merci à toi.

    Ce premier projet m'a donné envie de me plonger + encore dans perl.
    Je reviendrai très vite je pense !

    Bonne soirée

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 2
    Dernier message: 10/08/2012, 13h47
  2. [XSLT] Changer la valeur d'un attribut XML
    Par Rouxy007 dans le forum XSL/XSLT/XPATH
    Réponses: 11
    Dernier message: 14/02/2007, 23h06
  3. [Perl] comment installer XML sur Linux ?
    Par makohsarah dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 17/08/2006, 12h30
  4. [VB6]Lecture d'attributs XML
    Par BouB dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 15/05/2006, 16h01
  5. modifier la valeur d'un attribut xml
    Par totoche dans le forum ASP
    Réponses: 2
    Dernier message: 13/12/2005, 15h01

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