menu
1
2
3
4

Boîte A Outils 1

La première étape est l'extraction d'informations de l'arborescence des fils RSS du corpus. Grâce à la structuration imposée des données dans un fichier RSS, certaines zones du fichier peuvent être systématiquement ciblées pour en extraire le contenu. On verra qu'il existe deux façons d'extraire ces informations, ce qui a pour résultat la création de deux programmes distincts :

Le but est de produire deux types de sorties : un fichier TXT et un fichier XML contenant les titres et les descriptions des mises à jours à partir du corpus. Etant donné que les fils RSS appartiennent à différentes rubriques du journal (culture, sport etc.) un fichier de chaque type est produit pour chaque rubrique.




Parcourir l'aborescence

[ Vers le haut ]

On a vu que les fichiers sont organisés en dossier selon la date et l'heure de mise à jour et selon la rubrique. Pour traiter chacun de ces fichiers, le programme doit identifier quels objets de l'arborescence sont des dossiers et lesquels sont des fichiers. 'if (-d $file)' identifie si c'est un dossier – dans ce cas, on parcourt encore l'arborescence en explorant ce dossier jusqu'à ce que tous les fichiers soient identifiés. Les fichiers sont identifiés par : 'if (-f $file)'.

my $path = shift(@_); opendir(DIR, $path) or die "Problème d'ouverture du répertoire : $!\n"; my @files = readdir(DIR); closedir(DIR); foreach my $file (@files) { next if $file =~ /^\.\.?$/; # si ce n'est pas "." ou ".." $file = $path."/".$file; if (-d $file) # si c'est un dossier { &parcoursarborescencefichiers($file); #recurse! } if (-f $file) # si c'est un fichier { if ($file=~/\.xml$/) # si c'est un fichier xml # continuer le traitement ...


Phase de Pré-Traitement

[ Vers le haut ]

La première solution (Pure Perl) nécessite une phrase de pré-traitement assez importante. Pour que le texte s'affiche correctement et afin de comparer du texte extrait de fichiers sources différents, il est d'abord nécessaire d'harmoniser le contenu des fichiers, c'est à dire :

Les Encodages

La diversité des encodages et les problèmes qu'elle peut entraîner commencent à être très familiers. Il faudrait s'assurer que les fichiers soient tous écrits dans le même encodage au moment de la lecture et au moment de la sortie. Il faut un mécanisme qui détecte l'encodage afin de faire cela correctement et il y a deux manières de procéder :

  1. Appeler la commande Unix file afin de récupérer l'estimation de l'encodage qu'elle fournit. La commande 'system' permet d'invoquer une commande non-perl mais ne fournit pas de moyen de récupérer le résultat. Heureusement, mettre la commande entre ante-côtes a l'effet voulu.

    my $encodage=`file -i $ARGV[0] | cut -d= -f2`

    Le résultat de file -i (dont uniquement la partie qui spécifie l'encodage est sélectionnée (par la commande cut)) est récuperé et stocké dans la variable $encodage.
    N.B. Cette méthode ne fonctionne pas sous Windows car 'file' est une commande Unix.

    Un problème surgit à l'exécution du programme :

    Cannot find encoding "binary" at PremierBAO.pl line 100. Unsuccessful open on filename containing newline at PremierBAO.pl line 100. readline() on closed filehandle FILE at PremierBAO.pl line 105."


    Ce n'est pas un problème avec la commande 'file', mais un problème au moment de l'ouverture du fichier. File fournit un encodage - binary - qui n'est pas un encodage reconnu pour l'ouverture.. Ceci est évidemment un problème : il serait sage d'une part d'essayer une autre méthode (plus sûre) pour l'extraction d'encodage, et d'autre part mettre en place un mécanisme pour s'assurer que le fichier soit bien ouvert avant de procéder.

  2. Extraire l'encodage directement du fichier. A priori la première ligne du document RSS contient une déclaration du type du fichier, ainsi qu'une déclaration d'encodage, comme l'exemple suivant :

    <?xml version="1.0" encoding="UTF-8"?>


    Une expression régulière permet de le sélectionner :

    open(FILE,$file); my $firstLine=<FILE>; my $encodage=""; if($firstLine=~/encoding= ?['"]([^\'"]+)['"]/) { $encodage=$1; #extraire l'encodage } close(FILE); ...

    Si cette déclaration est trouvée dans le fichier, l'encodage, qui est précisément la partie de ce motif entre parenthèses, est stocké automatiquement dans la variable $1, d'où il peut être récupéré et stocké dans la variable $encodage.

Donc c'est avec la deuxième méthode qu'on va procéder. Et pour s'assurer qu'il n'a plus d'erreurs à l'ouverture du fichier au cas où aucun encodage ne serait détecté, le traitement qui suit appliquera uniquement sur les fichiers pour lesquels on peut l'identifier :

if (!($encodage eq "")) #si l'encodage n'est pas vide { # continuer le traitement ...


Lecture dans le bon encodage

Maintenant, afin d'ouvrir chaque fichier dans son encodage d'origine, il est utile de le spécifier lors de son ouverture :

open(FILE,"<:encoding($encodage)", $ARGV[0]);

Sortie dans le bon encodage

Il faut aussi s'assurer que l'encodage soit commun entre les fichiers traités. Quel que soit leur encodage d'origine, tous les fichiers seront convertis en UTF-8 (s'ils ne sont pas déjà en UTF-8). La bibliothèque XML UnicodeString possède une fonction (utf8) qui fait cette conversion sur la base de l'encodage d'origine fourni.

if (uc($encodage) ne "UTF-8") { # convertir les éléments à écrire utf8($titre); utf8($description); }

Harmonisation du formatage

Bien que les fichiers soient tous structurés de la même façon avec les mêmes balises, il n'y a rien qui oblige les fichiers à avoir exactement le même formatage. Pourvu que les balises soient conformes aux règles de la syntaxe RSS, ‘whitespace' (des sauts de ligne, des tabulations et des espaces) ne changent rien par rapport à la bonne formation du document.

Ainsi, il existe des fichiers RSS où tout le contenu est sur une seule ligne, des fichiers où chaque balise a sa propre ligne, et rien n'empêche le passage à la ligne à l'intérieur d'une balise.

Par contre, le programme perl doit pouvoir manipuler tous les fichiers et parcourir automatiquement et systématiquement l'arborescence de chaque fichier, quelque soit le formatage. Alors il faut prévoir une étape pour les harmoniser. Le format le plus facile à manipuler pour notre programme est celui où tout le contenu est sur une seule ligne.

Pour supprimer les éventuels sauts de ligne :

my $texte=""; while (my $ligne=<FILE>) { $ligne =~ s/\n//g; $ligne=~s/\r//g; $texte .= $ligne; }

Et pour coller les balises :

$texte=~s/> *<//g;



Extraction des Informations

[ Vers le haut ]

L'Extraction avec des Expressions Régulières

Les expressions régulières offrent un moyen très commode pour parcourir la structure arborescente des fichiers afin de viser certaines zones de texte et de les extraire. Pour extraire tous les titres et les descriptions, une boucle parcourt le fichier, repérant les parties du texte correspondant au motif spécifié. Les parenthèses permettent de viser certaines zones du texte afin de les isoler et les stocker séparément.

while ($texte=~/<item>.*?<title>(.*?)<\/title>.*?<description>(.*?)<\/description>/g) { my $titre=$1; my $description=$2; ...

Ce motif cherche les parties du texte qui contiennent les balises <title></title> et <description></description> directement sous la balise <item>, et les parenthèses isolent le contenu de chacune de ces balises, le stockant respectivement dans les variables $1 et $2.

De cette manière, d'autres informations relatives au fichier peuvent être facilement extraits : la date d'édition et le nom du flux, qui se situent à l'intérieur de la balise 'channel'.

$texte=~/<channel>.*?<title>(.*?)<\/title>.*?<pubDate>(.+?)<\/pubDate>.*?<\/channel>/; my $rubrique=&nettoyerRubriques($1); #nettoyer les rubriques print "RUBRIQUE : $rubrique\n"; my $date=&nettoyerRubriques($2); #extraire la date my $name=$file; #nom du fichier $name=~s/.*?(20.*)/$1/; #uniquement les fichiers XML contenant les mises à jour

Ces informations peuvent être ajoutées dans les fichiers de sorties, mais la plus importante est la rubrique, puisque le but est de produire une sortie par rubrique ! Cette variable peut être utilisée pour nommer les fichiers de sortie et pour créer une variable par rubrique qui sert à stocker le contenu de chacune (en vue de faire une sortie globale).

L'Extraction avec le Module XML::RSS

Il existe une deuxième solution pour arriver au même résultat. C'est une méthode qui tient compte du fait que les fichiers soient des fichiers XML et aient une structure arborescente. La première solution n'en tient pas compte et utilise les expressions régulières pour extraire les nœuds d'une manière similaire à l'extraction du texte d'un fichier texte brut.

Cette deuxième solution utilise XML::RSS, un module désigné spécifiquement pour les fichiers RSS.

Les étapes sont principalement les mêmes : il faut parcourir l'arborescence du dossier, en traitant tous les fichiers XML. Les sorties sont pareilles : un fichier texte et un fichier XML par rubrique, contenant les titres et descriptions de chaque item.

Ce qui change est la manière d'extraire ces informations. Faire du fichier un objet XML::RSS permet d'exploiter la structure arborescente pour atteindre les nœuds et de produire un objet hiérarchique au lieu de l'objet plat produit par la méthode qui utilise les regex.

my $rss = new XML::RSS; $rss->parsefile($file);

La première ligne crée un nouvel objet XML::RSS dont la référence est stockée dans la variable $rss. La deuxième signifie que l'objet à analyser en forme RSS est le fichier situé au chemin indiqué par $path.

L'objet RSS qui est créé est un tableau associatif qui contient des références vers d'autres références. Associer des références aux clés permet d'avoir des valeurs similaires au type 'liste' dans un tableau associatif, qui contient normalement des scalaires. Il est ainsi possible d'associer à un nœud 'item' des références vers les nœuds 'title' et 'description', qui sont contenus sous cette balise. Une boucle cherche tous les nœuds sous la balise 'items', et pour chaque nœud 'item' extrait le nœud 'title' et 'description'. Ceci se fait par l'opérateur 'flèche'.

foreach my $item (@{$rss->{'items'}}) { my $titre=$item->{'title'}; my $description=$item->{'description'}; … }

La rubrique peut être extraite de la même manière :

my $canal = $rss->{'channel'}; my $rubrique=$canal->{'title'}; $rubrique=nettoyerRubriques($rubrique); print "Rubrique : $rubrique\n";

L'avantage avec cette méthode est qu'il n'est pas nécessaire de faire l'harmonisation des fichiers (la suppression des sauts de lignes, les espaces entre les balises et le traitement des encodages différents). C'est le module XML::RSS qui gère ces étapes, et rend aussi la tâche de parcourir l'arborescence RSS plus facile. Un désavantage est que le déroulement du programme est plus chronophage.




Phase Post-Traitement des Informations

[ Vers le haut ]

Une fois les informations extraites, il faut veiller à leur bon affichage et à la non-duplication de ces informations.

Nettoyage du texte

Ayant déjà passé par une étape de transcodage, on pourrait se demander pourquoi il est nécessaire de faire une deuxième phase de nettoyage. Un premier nettoyage est nécessaire chez les rubriques. L'extraction de la rubrique se fait à l'intérieur du fichier et est de la forme : 'Le Monde.fr : à la Une' ou bien 'Europe - LeMonde.fr'. Ce qui nous intéresse est tout sauf ' : Le Monde.fr' ou ' - LeMonde.fr', qu'il faut enlever. Les rubriques vont être utilisées pour nommer des fichiers, donc il serait sage d'éviter des espaces et des caractères accentués. Pour simplifier, chaque rubrique est convertie en majuscules, tout espace supprimé, toute virgule remplacée par le tiret du huit et tout autre signe de ponctuation enlevé.

sub nettoyerRubriques { my $rubrique=shift; $rubrique=~s/Le Monde.fr//g; $rubrique=~s/LeMonde.fr//g; $rubrique=~s/É/e/g; $rubrique=~s/é/e/g; $rubrique=~s/è/e/g; $rubrique=~s/ê/a/g; $rubrique=~s/ë/e/g; $rubrique=~s/ï/i/g; $rubrique=~s/î/i/g; $rubrique=~s/à/a/g; $rubrique=~s/ô/o/g; $rubrique=~s/,/_/g; $rubrique=uc($rubrique); # mettre en majuscules $rubrique=~s/ //g; $rubrique=~s/[\.\:;\'\"\-]+//; return $rubrique; }

(La fonction shift enlève le premier élément de la liste d'arguments fournis et le renvoie.)

Les titres et les descriptions doivent également être nettoyés mais pas de la même façon. Ils contiennent certaines suites de caractères étranges, tels que &lt;, &amp; et &gt;. Ce sont des entités XML : des caractères codés selon la spécification XML pour éviter que ces caractères spéciaux soient interpretés comme faisant partie de la structure du document.

Il y a cinq entités XML prédéfinies (HTML en spécifie davantage) :

Pour remplacer les références XML par les caractères qu'ils représentent, le texte est passé par une fonction qui utilise les expressions régulières pour substituer l'un pour l'autre.

Comme avec la fonction 'nettoyerRubriqes', la fonction, nommée nettoyerTexte fait une copie de l'argument donné (le texte à nettoyer) et remplace les entités XML une par une par les caractères correspondants :

sub nettoyerTexte { my $tx=$_[0]; $tx=~s/&#38;/&/g; $tx=~s/&amp;/&/g; $tx=~s/&#34;/"/g; $tx=~s/&quot;/"/g; $tx=~s/&#39;/'/g; $tx=~s/&apos;/'/g; $tx=~s/&#60;/</g; $tx=~s/</</g; $tx=~s/&#62;/>/g; $tx=~s/>/>/g; $tx=~s/&#160;//g; $tx=~s/&nbsp;//g; $tx=~s/&#163;/£/g; $tx=~s/&pound;/£/g; $tx=~s/&#169;/©/g; $tx=~s/&#171;/«/g; $tx=~s/&laquo;/«/g; $tx=~s/&#187;/»/g; $tx=~s/&raquo;//g; $tx=~s/&#201;/É/g; $tx=~s/&Eacute;/É/g; $tx=~s/&#237;/î/g; $tx=~s/&icirc;/î/g; $tx=~s/&#239;/ï/g; $tx=~s/&iuml;/ï/g; $tx=~s/&#224;/à/g; $tx=~s/&agrave;/à/g; $tx=~s/&#226;/â/g; $tx=~s/&acirc;/â/g; $tx=~s/&#231;/ç/g; $tx=~s/&ccedil;/ç/g; $tx=~s/&#232;/è/g; $tx=~s/&egrave;/è/g; $tx=~s/&#233;/é/g; $tx=~s/&eacute;/é/g; $tx=~s/&#234;/ê/g; $tx=~s/&ecirc;/ê/g; $tx=~s/&#244;/ô/g; $tx=~s/&ocirc;/ô/g; $tx=~s/&#251;/û/g; $tx=~s/&ucirc;/û/g; $tx=~s/&#252;/ü/g; $tx=~s/&uuml;/ü/g; $tx=~s/&uuml;/ü/g; $tx=~s/\x9c/œ/g; $tx=~s/<br\/\>//g; # enlever tous les <br> $tx=~s/<img.*?\/>//g; # enlever les images $tx=~s/<a.*?>.*?<\/a>//g; # enlever des hyperliens $tx=~s/<![CDATA[(.*?)]]>/$1/g; # enlever l'enveloppe CDATA $tx=~ s/<[^>]>//g; # enlever toutes les autres balises $tx=~s/\.$//; # enlever un point final $tx=~s/&/et/g; # remplacer les arobas qui restent return $tx; }

Quelques remarques :

Il existe aussi un module perl téléchargeable qui permet de faire la même tâche : XML::Entities prend en argument le texte à décoder et renvoie dans une seule ligne le texte 'décodé' :

$description=XML::Entities::decode($description);

Non-duplication des informations

Le fait qu'il s'agisse de fichiers de mises à jour augmente la possibilité d'avoir des informations dupliquées dans les fichiers de sortie. Pour ne pas que de grandes quantités d'informations répétées influent faussement le résultat final, il faut un moyen de trier les informations déjà vues des informations nouvelles.

En perl les tableaux associatifs permettent d'associer une information unique à une valeur. En créant une de ces structures pour les titres et une autre pour les descriptions, il est possible de vérifier si les informations ont déjà été vues.

Les deux tableaux associatifs sont déclarés au début du programme :

my %dicoTitre=(); my %dicoDescription=();

Mais il est important de distinguer des informations dupliquées à l'intérieur d'une rubrique (qu'il faut éviter) des informations dupliquées à travers les rubriques, qu'il faut permettre. Si la même description appartient à deux rubriques, il faut un moyen de la faire apparaître dans les deux. Idéalement il faudrait un tableau associatif pour les titres et les descriptions de chaque rubrique, mais nommer les tableaux associatifs dynamiquement en utilisant la variable $rubrique est très compliqué en Perl. Une solution plus simple est d'utiliser un seul tableau pour tous les titres et un autre pour les descriptions et de préfixer chaque titre et chaque description de sa rubrique :

if (!((exists $dicoTitre{$rubrique.$titre}) && (exists $dicoDescription{$rubrique.$description}))) { $dicoTitre{$rubrique.$titre}="1"; $dicoDescription{$rubrique.$description}="1"; # continuer le traitement (écriture)...

L'item sera traité uniquement si les tableaux associatifs ne contiennent pas à la fois le titre et la description pour cette rubrique.

N.B. Un tri est effectué juste avant cette étape pour éviter les items dont soit la description soit le titre est vide (ceci peut arriver si un des deux contient uniquement des caractères enlevés au moment du nettoyage). Autrement ces items pourraient poser un problème pour la comparaison de la non-duplication des informations. D'ailleurs on pourrait considérer plus logique d'écrire un item uniquement s'il y a toutes les informations disponibles (titre et description).

if (!(($titre eq "")or($description eq ""))) { # continuer le traitement ...


Les Sorties

[ Vers le haut ]

Plusieurs sorties sont produites :

Les Sorties TXT

Les sorties en format TXT ne contiennent - évidemment - aucune balise. Elles contiennent simplement une liste des titres et des descriptions. Au moment d'écrire les titres et les descriptions dans ces fichiers, il faut faire attention de les préfixer d'un point pour bien délimiter le début et la fin de chaque titre et chaque description.

Les sorties TXT par rubrique sont concatenées au fur et à mesure du déroulement du programme. Dans l'étape de l'extraction des informations, la rubrique de chaque fichier peut être identifiée et stockée dans une variable. Cette variable est utilisée pour nommer les fichiers. Une fois le chemin défini, il suffit de créer le fichier s'il n'existe pas déjà ou de l'ouvrir s'il existe et dans les deux cas d'écrire les titres et les descriptions, séparés de points. Le fichier global étant déjà ouvert, l'écriture vers ce fichier peut se faire directement après.

#---------------- Sorties TXT -------------------> my $cheminTXT=$res.$rubrique.".txt"; # nommer le fichier en utilisant la variable 'rubrique' if (! -e $cheminTXT) #si c'est la première fois qu'on rencontre la rubrique { if (!open (FILEOUT,">:encoding(UTF-8)",$cheminTXT)) { die "Problème a l'ouverture du fichier $cheminTXT"; } print FILEOUT "$titre."." $description."; #écrire directement dans le fichier de sortie close(FILEOUT); #------- DUMPGLOBAL -----> print FILEglobTXT "$titre."." $description."; #écrire directement dans le fichier de sortie } else #si la rubrique a déjà été rencontrée { if (!open (FILEOUT,">>:encoding(UTF-8)",$cheminTXT)) { die "Problème a l'ouverture du fichier $cheminTXT"; } print FILEOUT "$titre."." $description."; #écrire directement dans le fichier de sortie close(FILEOUT); #------- DUMPGLOBAL -----> print FILEglobTXT "$titre."." $description."; #écrire directement dans le fichier de sortie }

La sortie globale est ouverte juste avant le lancement de la procédure parcoursarborescencefichiers (qui effectue le traitement), concaténée en cours de marche (ci-dessus) et fermée une fois tous les fils RSS sont traités.

#---- Sortie Globale TXT -> à concaténer au fur et à mesure ----> open(FILEglobTXT,">:encoding(UTF-8)", $res."1_SortieGlobale.txt"); #============= Appel au sub -> parcours =========> &parcoursarborescencefichiers($rep); #recurse! #================================================> #---- fermer la sortie Globale TXT -> fini !---> close FILEglobTXT;

Les Sorties XML

[ Vers le haut ]

Les sorties en format XML doivent être bien structurées, avec des balises XML. Donc au moment de la sortie, il faut organiser les informations avec des balises appropriées.

Les sorties par rubrique sont concaténées en cours de route (comme avec les sorties TXT). Le même principe est utilisé pour désigner dans quel fichier il faut écrire. Mais cette fois-ci la structuration des données sont mises en évidence par la présence des balises : une balise 'fichier' (avec son nom et date), à l'intérieur de laquelle est une liste d'items : chaque balise 'item' contient son titre et sa description.

A la rencontre d'un nouveau fichier, ses informations sont extraites et la rubrique identifiée. Avant d'ajouter de nouveaux items, le fichier correspondant à la rubrique est créé (s'il n'existe pas déjà) et ouvert (s'il existe déjà). Dans le cas où le fichier vient d'être créé, la balise racine du fichier XML doit être ouverte, y compris d'autres informations jugées utiles pour la désignation du fichier. Dans les deux cas, puisqu'il s'agit du traitement d'un nouveau fichier, on écrit une balise ouvrante <file>, qui sera fermée à la fin du traitement du fichier.

my $cheminXML=$res.$rubrique.".xml"; if (! -e $cheminXML) #si la première fois qu'on rencontre cette rubrique { if (!open (FILEOUT,">:encoding(UTF-8)",$cheminXML)) #création du fichier { die "Probleme a la creation du fichier $cheminXML : $!"; } #ouverture des balises XML du début du fichier print FILEOUT "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"; print FILEOUT "<PARCOURS>\n"; print FILEOUT "<NOM>Bawden</NOM>\n"; print FILEOUT "<$rubrique>\n"; print FILEOUT "<file>"; print FILEOUT "<name>$name</name>"; print FILEOUT "<date>$date</date>"; print FILEOUT "<items>"; close(FILEOUT); ${DumpXML."$rubrique"}=""; } else # le fichier existe déjà { if (!open (FILEOUT,">>:encoding(UTF-8)",$cheminXML)) { die "Problème a l'ouverture du fichier $cheminXML"; } print FILEOUT "<file>"; print FILEOUT "<name>$name</name>"; print FILEOUT "<date>$date</date>"; print FILEOUT "<items>"; close(FILEOUT); }

Et à la fin du traitement du fichier :

#------- Fermer la balise file pour chaque fichier xml ------> if (!open (FILEOUT,">>:encoding(UTF-8)",$cheminXML)) { die "Problème a la creation du fichier .$cheminXML"; } print FILEOUT "</items>"; print FILEOUT "</file>"; close(FILEOUT);

Les items sont ajoutés un par un à l'intérieur de la boucle while. Chaque paire titre-description est écrite sous une balise <item> et chacune entourée de sa balise appropriée.

if (!open (FILEOUT,">>:encoding(UTF-8)",$cheminXML)) { die "Problème a l'ouverture du fichier $cheminXML"; } print FILEOUT "<item>\n"; print FILEOUT "<titre>".$titre."</titre>\n<description>".$description."</description>\n"; print FILEOUT "</item>\n"; close(FILEOUT);

Pour assurer la bonne structuration de ces fichiers, il faut aussi fermer les balises ouvertes à leur création. Ceci doit se faire à la fin du programme, une fois que toutes les informations sont ajoutées. La boucle suivante parcourt le contenu du dossier de sortie et écrit les balises fermantes nécessaires pour tous les fichiers XML qui ne sont pas la sortie globale (qui sera traitée séparément).

#-------------------------------------------------> # Fermer les sorties XML par rubriques #-------------------------------------------------> opendir(DIR, $res) or die "Erreur d'ouverture du repertoire: $!\n"; my @sorties = readdir(DIR); closedir(DIR); foreach my $sortie (@sorties) { if ($sortie=~/(.+?)\.xml$/ && $1 != "1_SortieGlobale") { my $rub=$1; open(FILE,">>:encoding(UTF-8)", $res.$sortie); print FILE "</".$rub.">\n";; print FILE "</PARCOURS>\n"; close(FILE); } }

La sortie globale XML est structurée par rubrique. Ceci veut dire que son contenu ne peut être écrit qu'à la fin du traitement de tous les fichiers. Pour chaque rubrique il doit exister une variable pour stocker tous les items associés à cette rubrique jusqu'à l'écriture dans le fichier à la fin du programme.

Bien que ça ne soit pas toujours considéré comme une décision très sage, je nomme dynamiquement les variables en utilisant la variable $rubrique. Il n'est pas certain non plus que cette méthode marche quand 'strict refs' sont activés. Mais pour cette tâche spécifique, il semble être une bonne idée - surtout parce qu'il est possible de retrouver toutes ces variables créées via les noms des fichiers créés.

#------- Création du dumpglobal pour chaque rubrique -----> ${"DumpXML".$rubrique}.="<item>\n<titre>".$titre."</titre>\n<description>".$description."</description>\n</item>\n";

Une fois tous les fichiers traités, la sortie globale peut être construite :

#----------BAO1 - Création de la Sortie Globale XML------------> open(FILEglobXML, ">:encoding(UTF-8)", $res."1_SortieGlobale.xml"); print FILEglobXML "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"; print FILEglobXML "<PARCOURS>\n"; print FILEglobXML "<NOM>BAWDEN</NOM>\n"; print FILEglobXML "<FILTRAGE>";

Pour l'écriture de chaque rubrique, on peut toujours exploiter la boucle pour la fermeture des rubriques, afin d'avoir la liste complète des rubriques :

foreach my $sortie (@sorties) { if ($sortie=~/(.+?)\.xml$/ && $1 != "1_SortieGlobale") { my $rub=$1; open(FILE,">>:encoding(UTF-8)", $res.$sortie); print FILE "</".$rub.">\n";; print FILE "</PARCOURS>\n"; close(FILE); #------ Sortie Globale Ecriture de contenu ----> print FILEglobXML "<$rub>\n"; print FILEglobXML ${"DumpXML".$rub}; #écrire le dump global de chaque rubrique print FILEglobXML "</$rub>"; } } #-------------- Sortie Globale Fermeture------------> print FILEglobXML "</FILTRAGE>\n"; print FILEglobXML "</PARCOURS>\n"; close(FILEglobXML);

A l'intérieur de la boucle, on écrit dans le fichier global une balise au nom de la rubrique actuelle et le contenu de la variable pour cette rubrique (une liste d'items contenant chacun un titre et une description). A la fin de la boucle il ne faut pas oublier de fermer toutes les balises du fichier !



Résumé

[ Vers le haut ]

Les deux méthodes d'extraction du contenu des fils seront testées, ce qui signifie l'écriture de deux programmes séparés :

Les compteurs à l'intérieur de chaque programme permettent de s'assurer qu'il y ait le même nombre d'items en sortie à la fin du programme. Heureusement, c'est le cas ! (ce qui montre que l'expression régulière est assez précise). Le nombre total des items en sortie est de....53 461, sachant que sans tenir compte des duplications il y en a plus de 130 000 !!

Visualisation HTML

[ Vers le haut ]

Les résultats de cette étape peuvent être présentés en format HTML après une transformation XSLT des sorties XML.

La feuille de styles XSL rattachée à chaque document XML transforme chaque rubrique en un tableau de titres et de descriptions, rangés par fichier :

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html" version="4.0" encoding="utf-8" indent="yes"/> <xsl:template match="/PARCOURS"> <xsl:variable name="rubrique" select="local-name(./*[preceding-sibling::NOM])"/> <!-- Nom du rubrique --> <html> <head> <meta charset="utf-8"/> <link rel="stylesheet" type="text/css" href="bao1html.css"/><!-- css pour enjoliver le html --> <title><xsl:value-of select="$rubrique"/></title><!-- Nom du rubrique --> <link rel="icon" type="image/ico" href="../../Images/bao.ico"/> <!-- Favicon --> </head> <body> <div id="contenu"> <!-- Conteneur --> <h1><xsl:value-of select="$rubrique"/></h1> <table> <xsl:apply-templates select="*/file"/> <!-- Contenu du tableau --> </table> </div> </body> </html> </xsl:template> <xsl:template match="file"> <!-- Pour chaque fichier --> <xsl:if test="./items/item"><!-- S'il existe des items dans le fichier --> <xsl:variable name="fullname" select="./name"/><!-- Nom du fichier --> <xsl:variable name="name" select="substring-before($fullname, '.')"/> <!--Nom du ficher sans l'extension --> <xsl:variable name="lengthname" select="string-length($name)"/><!-- Longueur du nom du fichier --> <xsl:variable name="filename" select="substring($name, $lengthname - 13, $lengthname)"/><!-- Nom du fichier sans le chemin --> <tr> <th colspan="2" class="fileheader"><xsl:value-of select="$filename"/><xsl:text> (</xsl:text><xsl:value-of select="date"/><xsl:text></xsl:text></th></tr><!-- Diviseur par fichier --> <tr><th>Titre</th><th>Description</th></tr><!-- Titres des colonnes : titre et fichiers--> <xsl:apply-templates select="items/item"/><!-- Ajouter des items --> </xsl:if> </xsl:template> <xsl:template match="item"> <tr> <td><xsl:value-of select="titre"/></td><!-- Ajouter le titre --> <td><xsl:value-of select="description"/></td><!-- Ajouter la description --> </tr> </xsl:template> </xsl:stylesheet>

CINEMA

0,2-3476,1-0,0 (Sat, 31 Mar 2012 14:25:08 GMT)
TitreDescription
Julie Delpy récidiveLes choix culture de "M", le magazine du "Monde"/Cinéma. "2 Days in New York"
Faiseurs de culture : Sylvain Chomet à AlèsA la veille de la présidentielle, "Le Monde" donne la parole à ceux qui font bouger les régions dans le domaine culturel
"Hunger Games" : l'apocalypse pop servie par le marketingLa franchise entend détrôner les sagas "Twilight" et "Harry Potter" auprès des ados. Décryptage d'un lancement savamment élaboré
......
[ Cliquez sur le tableau pour le visualiser ]

ALAUNE

0,2-3208,1-0,0 (Sun, 01 Apr 2012 17:18:03 GMT
TitreDescription
Ligue 1 : Lille croit de nouveau au titreEn battant Toulouse dimanche à domicile grâce à une nouveau festival d'Eden Hazard , les Lillois ont démontré qu'il ne fallait pas les oublier dans la course au titre en Ligue 1, à huit journées du dénouement
Mort de la résistante Lise LondonLa veuve d'Artur London, dont le procès stalinien a été rendu célèbre par son livre et le film "L'Aveu", est morte à l'âge de 96 ansl
"Affaire Merah : l'avocate du père dit détenir des vidéos prouvant "la liquidation" du tueurSelon Me Zahia Mokhtari, "Merah a été manipulé et utilisé par les services français et a ensuite été liquidé pour que la vérité ne voie pas le jour"
......
[ Cliquez sur le tableau pour le visualiser ]

download

Cliquer sur les liens pour télécharger les fichiers et les scripts.

Site et design par Rachel Bawden, Plurital 2013