Maintenant que nous possédant des fichiers tagués, résultat de la boite à outils 2, nous pouvons passer à la 3eme boite à outils qui consiste à rechercher les patrons syntaxiques.
Le script de la boite à outils 3 qui est fourni par M. Rachid Belmouhoub à été récupéré sur le site du cours.
Le programme va prendre en argument le dossier contenant les fichiers XML de la boite à outils 2 et le fichier contenant les motifs à extraire qui sont dans notre example toutes les suites noms adjectifs, et avec l’aide de la requête xPath renvoi un fichier texte par patron.
Le programme est constitué d’une fonction &construit_XPath qui crée le chemin xPath selon les motifs fournis.
# routine de construction des chemins XPath sub construit_XPath{ # On récupère la ligne du motif recherché my $local_ligne=shift @_; # initialisation du chemin XPath my $search_path=""; # on supprime avec la fonction chomp un éventuel retour à la ligne chomp($local_ligne); #enlever les retours a la ligne # on élimine un éveltuel retour chariot hérité de windows $local_ligne=~ s/\r$//; # Construction au moyen de la fonction split d'un tableau dont chaque #élément a pour valeur un élément du motif recherché my @tokens=split(/ /,$local_ligne); #separer les patterns par un espace # On commence ici la construction du chemin XPath # Ce chemin correspond au premier noeud "element" de l'arbre XML qui répond #au motif cherché #chercher un element qui contient parmi ses fils data un attribut type #(despecialiser le @ et type). $search_path="//element[contains(data[\@type=\"type\"],\"$tokens[0]\")]"; # Initialisation du compteur pour la boucle de construction du chemin XPath #puisqu'on a plusieurs elements dans notre motif on fait une boucle #pour affiner la requete Xpath my $i=1; while ($i < $#tokens) { #concatener les conditions pour que "element" satisfasse toutes les conditions $search_path.="[following-sibling::element[1][contains(data[\@type=\"type\"], ~\"$tokens[$i]\")]"; $i++; }
et la fonction &extract_pattern qui extrait les motifs trouvés.
sub extract_pattern{ my $file=shift; # On récupère la ligne du motif recherché my $ext_pat_ligne= shift @_; #@_: tableau des arguments passes a la procedure my $rub=shift; # Appel de la fonction construit_XPath pour le motif lu à la #ligne courrante du fichier de motif #construire le chemin Xpath pour trouver dans le bon "element" my ($search_path,@tokens) = &construit_XPath($ext_pat_ligne,$rub); # définition du nom du fichier de résultats pour le motif en utilisant la fonction join #join sur un tableau colle les uns aux autres avec un "_" my $match_file = $sortie.$rub."-extract-".join('_', @tokens).".txt"; # Ouverture du fichier de résultats encodé en UTF-8 #pas necessaire le enconding open(MATCHFILE,">:encoding(UTF-8)", "$match_file") or die "can't open $match_file: $!\n"; # création de l'objet XML::XPath pour explorer le fichier de sortie tree-tagger XML #construire une classe my $xp = XML::XPath->new( filename => $dossier."/".$file ) or die "big trouble"; # Parcours des noeuds du ficher XML correspondant au motif, au moyen de la méthode findnodes # qui prend pour argument le chemin XPath construit précédement # avec la fonction "construit_XPath" #chercher les "elements" qui satisfont le chemin construit en haut foreach my $noeud ( $xp->findnodes($search_path)) { # Initialisation du chemin XPath relatif du noeud "data" contenant # la forme correspondant au premier élément du motif # Ce chemin est relatif au premier noeud "element" du bloc retourné # et pointe sur le troisième noeud "data" fils du noeud "element" # en l'identifiant par la valeur "string" de son attribut "type" my $form_xpath=""; #chercher le troisieme fils data (chercher le fils data dont l'attribut type est string) $form_xpath="./data[\@type=\"string\"]"; # Initialisation du compteur pour la boucle d'éxtraction des formes correspondants # aux éléments suivants du motif my $following=0; # Recherche du noeud data contenant la forme correspondant au premier élément du motif # au moyen de la fonction "find" qui prend pour arguments: # 1. le chemin XPath relatif du noeud "data" # 2. le noeud en cours de traitement dans cette boucle foreach # la fonction "find" retourne par défaut une liste de noeuds, dans notre cas cette liste # ne contient qu'un seul élément que nous récupérons avec la fonction "get_node" # enfin nous en imprimons le contenu textuel au moyen de la méthode string_value #ecrire dans le fichier print MATCHFILE $xp->find($form_xpath,$noeud)->get_node(1)->string_value," "; # Boucle d'éxtraction des formes correspondants aux éléments suivants du motif # On descend dans chaque noeud element du bloc while ( $following < $#tokens) { # Incrémentation du compteur $following de cette boucle d'éxtraction des formes $following++; # Construction du chemin XPath relatif du noeud "data" contenant # la forme correspondant à l'élément suivant du motif # Notez bien l'utilisation du compteur $following tant dans la condition de la boucle ci-dessus # que dans la construction du chemin relatif XPath #calculer le chemin qui va se trouver dans le troisieme fils data my $following_elmt="following-sibling::element[".$following."]"; $form_xpath=$following_elmt."/data[\@type=\"string\"]"; #concatenation # Impression du contenu textuel du noeud data contenant #la forme correspondant à l'élément suivant du motif print MATCHFILE $xp->find($form_xpath,$noeud)->get_node(1)->string_value," "; # Incrémentation du compteur $following de cette boucle d'éxtraction des formes # $following++; } #rajouter un retour a ligne pour que les motifs de correspondance soit separes par un retour a la ligne print MATCHFILE "\n"; } # Fermeture du fichiers de motifs close(MATCHFILE); }
Le lancement du programme a renvoyé des erreurs notamment une qui a été réglée en supprimant les balises contenant les métadonnées de l'encodage, manuellement avec une expression régulière
Le deuxième problème est de taille, le programme ne peut pas supporter les fichiers qui dépassent les 20 MO
Du coup certains fichiers n'ont pas pu être traité