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

Langage Perl Discussion :

parser un document xml/xhtml


Sujet :

Langage Perl

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 330
    Points : 93
    Points
    93
    Par défaut parser un document xml/xhtml
    Bonjour,

    J'ai un fichier xhtml qui en gros ressemble a cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <?xml version="1.0" encoding="utf-8"?>
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
    <head>
    ...
    </head>
    <div class="text">
    <p><span><span> paragraphe1 </span></span></p>
     
    <p><span><span> paragraphe2 </span></span></p>
     
    </div>
    je souhaiterai transformer ce fichier pour obtenir cela en sortie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <P>
    paragraphe1
    <P>
    paragraphe2
    Je recherche un parser xml/xhtml qui me permettrait de faire cela simplement. Je prefere utiliser un parser car par la suite j'aurai peut etre d'autres manipulation a realiser.

    pour le moment j'ai tenter d'utiliser MojoOM mais cela ne renvoi rien:
    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
     
    #!/usr/bin/env perl
     
    use strict;
    use warnings;
    use feature 'say';
    use Mojo::DOM;
     
    # slurp all DATA lines
    my $dom = Mojo::DOM->new(do { local $/; <DATA> });
     
    say $_->text for $dom->at('.text')->find('p')->each;
     
    __DATA__
    <div class="text">
    <p><span><span><span>para1</span></span></span></p>
    <p><span><span><span>para2</span></span></span></p>
    </div>
    merci

  2. #2
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Peut-être l'un des modules XML du CPAN: par exemple, XML:: Parser, XML::LibXML.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 330
    Points : 93
    Points
    93
    Par défaut
    Citation Envoyé par Lolo78 Voir le message
    Peut-être l'un des modules XML du CPAN: par exemple, XML:: Parser, XML::LibXML.
    J'ai choisi LibXML mais pour le moment ce n'est pas exactement ce que je veux.

    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
     
    #!/usr/bin/perl
    use strict;
    use warnings;
    use XML::LibXML;
    use utf8; binmode(STDOUT, ":encoding(UTF-8)");    use open qw( :encoding(UTF-8) :std );
     
    my $FichierXML = 'test.xml';
    my $parser     = XML::LibXML->new();
     
    my $tree = $parser->parse_file($FichierXML);
     
    my $root = $tree->getDocumentElement;
     
    # Balise para
    my @para = $root->getElementsByTagName('p');
    foreach my $childid (@para) {
    	print "<P>"."\n";
    	print $childid->getElementsByTagName('span')."\n";
     
    }
    j'aimerai avoir tout le texte contenu dans les balises p; le problème est que cette balise contient des sous noeuds span.

    Comment puis-je faire ?

  4. #4
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Citation Envoyé par knebhi Voir le message
    pour le moment j'ai tenter d'utiliser MojoOM mais cela ne renvoi rien:
    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
     
    #!/usr/bin/env perl
     
    use strict;
    use warnings;
    use feature 'say';
    use Mojo::DOM;
     
    # slurp all DATA lines
    my $dom = Mojo::DOM->new(do { local $/; <DATA> });
     
    say $_->all_text for $dom->at('.text')->find('p')->each;
     
    __DATA__
    <div class="text">
    <p><span><span><span>para1</span></span></span></p>
    <p><span><span><span>para2</span></span></span></p>
    </div>
    merci
    Change l'appel à la méthode "text" par l'appel à la méthode "all_text"
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 330
    Points : 93
    Points
    93
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Change l'appel à la méthode "text" par l'appel à la méthode "all_text"
    merci ça fonctionne très bien. par contre j'aimerai mettre un marqueur entre chaque paragraphe comme un # ou autre chose.

    quelle méthode je peux utiliser ?

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Pourrais-tu donner un exemple de ce que tu veux obtenir ?
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 330
    Points : 93
    Points
    93
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Pourrais-tu donner un exemple de ce que tu veux obtenir ?
    en gros je veux récupérer tout le texte contenu dans les éléments <p> - mais seulement les <p> contenu dans la <div class="text">.

    au final je souhaite insérer une balise <P> entre chaque paragraphe pour obtenir ce résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <P>
    paragraphe1
    <P>
    paragraphe2

  8. #8
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Comme ceci ?
    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
    #!/usr/bin/env perl
     
    use strict;
    use warnings;
    use feature 'say';
    use Mojo::DOM;
     
    # slurp all DATA lines
    my $dom = Mojo::DOM->new(do { local $/; <DATA> });
     
    $dom->at('.text')->find('p')->each(sub { $_->content($_->all_text()) });
    say "$dom";
    __DATA__
    <div class="text">
    <p><span><span><span>para1</span></span></span></p>
    <p><span><span><span>para2</span></span></span></p>
    </div>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $ perl 1.pl
    <div class="text">
    <p>para1</p>
    <p>para2</p>
    </div>
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 330
    Points : 93
    Points
    93
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Comme ceci ?
    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
    #!/usr/bin/env perl
     
    use strict;
    use warnings;
    use feature 'say';
    use Mojo::DOM;
     
    # slurp all DATA lines
    my $dom = Mojo::DOM->new(do { local $/; <DATA> });
     
    $dom->at('.text')->find('p')->each(sub { $_->content($_->all_text()) });
    say "$dom";
    __DATA__
    <div class="text">
    <p><span><span><span>para1</span></span></span></p>
    <p><span><span><span>para2</span></span></span></p>
    </div>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $ perl 1.pl
    <div class="text">
    <p>para1</p>
    <p>para2</p>
    </div>
    non en fait je ne veux que le texte puis un retour chariot et enfin une balise <P>
    mais je ne veux fermer la balise

  10. #10
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je ne crois pas qu'il soit possible de remplacer un élément par un arbre non conforme à XML (c'est à dire des balises non fermée) avec Mojolicious : si tu essayes ceci :
    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
    #!/usr/bin/env perl
     
    use strict;
    use warnings;
    use feature 'say';
    use Mojo::DOM;
     
    # slurp all DATA lines
    my $dom = Mojo::DOM->new(do { local $/; <DATA> });
    $dom->at('.text')->find('p')->each(sub { $_->replace('<p>'.$_->all_text()) });
    say "$dom"; 
    __DATA__
    <div class="text">
    <p><span><span><span>para1</span></span></span></p>
    <p><span><span><span>para2</span></span></span></p>
    </div>
    La balise de fermeture <p/> est automagiquement ajoutée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ perl 1.pl
    <div class="text">
    <p>para1</p>
    <p>para2</p>
    </div>
    Je pense, par extension, que ce n'est pas possible avec n'importe quel module manipulant un "DOM"
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  11. #11
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Il doit cependant être possible de retraiter manuellement le contenu généré par DOM juste avant der l'imprimer.

  12. #12
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Autant tout faire en regexp alors, non ?
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  13. #13
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Autant tout faire en regexp alors, non ?
    Bah, à la limite, pourquoi pas?

    Voici un fil sur Perlmonks aujourd'hui ou hier dans lequel je dis que c'est faisable dans certains cas. Et j'ai eu (à l'heure actuelle) 25 votes positifs et aucun négatif. A l'heure où j'écris, mon post figure même en troisième meilleure position des posts de la journée. Ce qui prouve que les moines de Perlmonks sont moins intégristes qu'on pourrait le croire (pour des moines, je veux dire).

    Mais, personnellement, je crois que je préférerais ici retraiter le résultat produit par DOM, ce qui est assez simple, plutôt que de gérer le parsing du HTML.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 330
    Points : 93
    Points
    93
    Par défaut
    j'ai retraité le resultat (j'ai effacer quelques balises)- mais bon j'aurai tout un tas de fichiers donc c'est pour cela que je souhaitais faire ça le plus
    proprement possible.

    merci encore

  15. #15
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 26
    Points : 18
    Points
    18
    Par défaut Peut-on acceder directement a une valeur d'un champ XML
    Bonjour,
    J'aurais une question concernant le lecture d'un champ XML:

    J'ai un xml de la forme
    ----------------------------------------------------------------------
    <General>
    <Code name="ZA1">
    <Type>BINARY</Type>
    </Code>
    <Code name="Y61">
    <Type>BINARY2</Type>
    </Code>
    <Code name="Z61">
    <Type>BINARY3</Type>
    </Code>
    </General>
    ---------------------------------------------------------------------------

    Le scirpt Perl lit un fichier texte qui conrtient le "Code name", (ZA1,Y61,Z61,...) et je doit récupérer le "Type" dans le xml.
    J'utilise avec XML::Simple

    Pas de problème pour le récupéerer en faisant :
    -----------------------------------------------------
    my $parser = XML::Simple->new();
    $monxml=toto.xml;
    my $xml=$parser->XMLin($monxml, keyattr=>['General']);
    my $xmlgeneral=$xml->{General};
    my $Code=$xmlgeneral->{Code};
    foreach my $fab (@{$Code}) {
    if ($fab->{name} eq "$mavaleur") { # $mavaleur sera soit ZA1,Y61,Z61,...
    print "Product type found ".$fab->{Type}."\n";
    }
    }

    Mais je voudrais savoir s'il est possible de récupérer la valeur du tag <Type> sans passer par une boucle foreach
    J'ai essayer plusieurs syntaxe du style $Code->$mavaleur->{Type} mais sans succés.

    Merci,

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

Discussions similaires

  1. parser un document xml
    Par TERRIBLE dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 09/03/2008, 08h06
  2. [SAX] parser un document xml
    Par skyangel dans le forum Entrée/Sortie
    Réponses: 0
    Dernier message: 11/12/2007, 19h18
  3. [DOM4J] Parser un document XML avec DOM
    Par kroax dans le forum Format d'échange (XML, JSON...)
    Réponses: 6
    Dernier message: 23/11/2007, 01h48
  4. [SimpleXML] parser un document xml distant
    Par turican2 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 22/05/2007, 15h18
  5. Parser mon document XML.
    Par Bruno13 dans le forum Langage
    Réponses: 3
    Dernier message: 28/01/2006, 14h30

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