1 #/usr/bin/perl
  2 <<DOC; 
  3 Nom : Rachid Belmouhoub
  4 Avril 2012
  5  usage : perl xpath.pl fichier_tag fichier_motif
  6 DOC
  7 
  8 use strict;
  9 use utf8;
 10 use XML::XPath;
 11 use 5.014;
 12 
 13 # Définition globale des encodage d'entrée et sortie du script à utf8
 14 binmode STDIN,  ':encoding(utf8)';
 15 binmode STDOUT, ':encoding(utf8)';
 16 
 17 # On vérifie le nombre d'arguments de l'appel au script ($0 : le nom du script)
 18 #if($#ARGV!=1){print "usage : perl $0 fichier_tag fichier_motif";exit;}
 19 die "usage : perl $0 fichier_tag fichier_motif dossier/fichiersortie" unless (@ARGV==3);
 20 # Enregistrement des arguments de la ligne de commande dans les variables idoines
 21 my $tag_file= shift @ARGV;
 22 my $patterns_file = shift @ARGV;
 23 #### variable perso ####
 24 my $saveName = shift @ARGV;
 25 
 26 # Ouverture du fichiers de motifs
 27 open(PATTERNSFILE, $patterns_file) or die "can't open $patterns_file: $!\n";
 28 
 29 # lecture du fichier contenant les motifs, un motif par ligne (par exemple : NOM ADJ)
 30 while (my $ligne = <PATTERNSFILE>) {
 31     # Appel à  la procédure d'extraction des motifs
 32     &extract_pattern($ligne);
 33 }
 34 
 35 # Fermeture du fichiers de motifs
 36 close(PATTERNSFILE);
 37 
 38 # routine de construction des chemins XPath
 39 sub construit_XPath{
 40     # On récupère la ligne du motif recherché
 41     my $local_ligne=shift @_;
 42 
 43     # initialisation du chemin XPath
 44     my $search_path="";
 45 
 46     # on supprime avec la fonction chomp un éventuel retour à la ligne
 47     chomp($local_ligne);
 48 
 49     # on élimine un éveltuel retour chariot hérité de windows
 50     $local_ligne=~ s/\r$//;
 51 
 52     # Construction au moyen de la fonction split d'un tableau dont chaque élément a pour valeur un élément du motif recherché
 53     my @tokens=split(/ /,$local_ligne);
 54 
 55     # On commence ici la construction du chemin XPath
 56     # Ce chemin correspond au premier noeud "element" de l'arbre XML qui répond au motif cherché 
 57     my $search_path="//element[contains(data[\@type=\"type\"],\"$tokens[0]\")]";
 58 
 59     # Initialisation du compteur pour la boucle de construction du chemin XPath
 60     my $i=1;
 61     while ($i < $#tokens) {
 62         $search_path.="[following-sibling::element[1][contains(data[\@type=\"type\"],\"$tokens[$i]\")]";
 63         $i++;
 64     }
 65     my $search_path_suffix="]";
 66 
 67     # on utilise l'opérateur x qui permet de répéter la chaine de caractère à sa gauche autant de fois que l'entier à sa droite,
 68     # soit $i fois $search_path_suffix
 69     $search_path_suffix=$search_path_suffix x $i;
 70 
 71     # le chemin XPath final
 72     $search_path.="[following-sibling::element[1][contains(data[\@type=\"type\"],\"".$tokens[$#tokens]."\")]"
 73                                 .$search_path_suffix;
 74         # print  "$search_path\n";
 75 
 76     # on renvoie à la procédure appelante le chein XPath et le tableau des éléments du motif
 77     return ($search_path,@tokens);
 78 }
 79 
 80 # routine d'extraction du motif
 81 sub extract_pattern{
 82     # On récupère la ligne du motif recherché
 83     my $ext_pat_ligne= shift @_;
 84 
 85     # Appel de la fonction construit_XPath pour le motif lu à la ligne courrante du fichier de motif
 86     my ($search_path,@tokens) = &construit_XPath($ext_pat_ligne);
 87 
 88     # définition du nom du fichier de résultats pour le motif en utilisant la fonction join
 89 
 90 #### chemin perso ####
 91     #my $match_file = "res_extract-".join('_', @tokens).".txt";
 92     mkdir ("./ResultatBaoXpathPerl");
 93     my $match_file ="./ResultatBaoXpathPerl/res_extract-".join('_', @tokens)."$saveName.txt";
 94     # Ouverture du fichiers de résultats encodé en UTF-8
 95     open(MATCHFILE,">:encoding(UTF-8)", "$match_file") or die "can't open $match_file: $!\n";
 96 
 97     # création de l'objet XML::XPath pour explorer le fichier de sortie tree-tagger XML
 98     my $xp = XML::XPath->new( filename => $tag_file ) or die "big trouble";
 99 
100     # Parcours des noeuds du ficher XML correspondant au motif, au moyen de la méthode findnodes
101     # qui prend pour argument le chemin XPath construit précédement
102     # avec la fonction "construit_XPath"
103     foreach my $noeud ( $xp->findnodes($search_path)) {
104         # Initialisation du chemin XPath relatif du noeud "data" contenant
105         # la forme correspondant au premier élément du motif
106         # Ce chemin est relatif au premier noeud "element" du bloc retourné
107         # et pointe sur le troisième noeud "data" fils du noeud "element"
108         # en l'identifiant par la valeur "string" de son attribut "type"
109         my $form_xpath="";
110         $form_xpath="./data[\@type=\"string\"]";
111 
112         # Initialisation du compteur pour la boucle d'éxtraction des formes correspondants
113         # aux éléments suivants du motif
114         my $following=0;
115 
116         # Recherche du noeud data contenant la forme correspondant au premier élément du motif      
117         # au moyen de la fonction "find" qui prend pour arguments:
118         #           1. le chemin XPath relatif du noeud "data"
119         #           2. le noeud en cours de traitement dans cette boucle foreach
120         # la fonction "find" retourne par défaut une liste de noeuds, dans notre cas cette liste
121         # ne contient qu'un seul élément que nous récupérons avec la fonction "get_node"
122         # enfin nous en imprimons le contenu textuel au moyen de la méthode string_value
123         print MATCHFILE $xp->find($form_xpath,$noeud)->get_node(1)->string_value," ";
124 
125         # Boucle d'éxtraction des formes correspondants aux éléments suivants du motif
126         # On descend dans chaque noeud element du bloc
127         while ( $following < $#tokens) {
128             # Incrémentation du compteur $following de cette boucle d'éxtraction des formes
129             $following++;
130 
131             # Construction du chemin XPath relatif du noeud "data" contenant
132             # la forme correspondant à l'élément suivant du motif
133             # Notez bien l'utilisation du compteur $folowing tant dans la condition de la boucle ci-dessus
134             # que dans la construction du chemin relatif XPath
135             my $following_elmt="following-sibling::element[".$following."]";
136             $form_xpath=$following_elmt."/data[\@type=\"string\"]";
137 
138             #   Impression du contenu textuel du noeud data contenant la forme correspondant à l'élément suivant du motif
139             print MATCHFILE $xp->find($form_xpath,$noeud)->get_node(1)->string_value," ";
140 
141             # Incrémentation du compteur $following de cette boucle d'éxtraction des formes
142             # $following++;
143         }
144         print MATCHFILE "\n";
145     }
146     # Fermeture du fichiers de motifs
147     close(MATCHFILE);
148 }