Bonjour à tous (1er post \o/)
d'habitude j'arrive (à peu près & tant bien que mal) à me débrouiller tout seul, mais la je sèche, alors je viens crier au secours
je vais essayer de décrire le mieux possible comment se comporte mon corpus.
je travail sur des fichiers xhtml de textes de loi en diachronie afin d'en étudier les variations... bref, je vous passe certains détails. Mais ceux ci vous aideront peut être pour me guider !
1 ) Ces fichiers sont structurés avec pleins de <div> imbriquées dont l'ouvrante porte un attribut renseignant sur sa place dans la hierarchie.
code > livres > parties > chapitrse > sections > sous sections > paragraphes > sous paragraphes > articles... (la liste est non exhaustive et non finie...)
bref, un code contenant des livres contenant eux même des chapitres... blablabla
2 ) tous les niveaux de hiérarchie ne sont pas présents obligatoirement.
(Dans un livre on peut arriver directement sur des articles).
3 ) dans un script perl (autre que celui que je vous ai mis) je parse ces <div> à base de regexp mais vous imaginez la taille des regexp.. qui me sortent une "segmentation fault" quand les fichiers commencent à dépasser 4 ou 5 Mo (mais peut être ce n'est pas du à leur taille mais à leur structure). SI c'est du à leur taille, y'a ptete moyen d'augmenter la taille de la pile qui doit ptete merde du fait de la complexité de la regexp.
Bref, dans mes regexp, quand je veux matcher un élement de type <div attr="..."> ... </div> (qui contient lui même des div à la pelle) je suis obligé de détailler l'intérieur avec les div que je peux rencontrer (ou pas, donc y'a plein de * ou/et de ? imbriqués) afin de matcher la bonne </div> fermante. Ptete pour ça que ça plante !
bref, traitement très lourd, et peut être très stupide.
4 ) je me suis donc dit : "tiens, vais essayer de pré-traiter le xml histoire de faciliter la vie à mon script derrière".
j'ai donc essayé de créer une routine (voir tout en bas) qui pour une div ouvrante donnée va récupérer la fermante, et remplacer le div par l'attribut
donc au lieu d'avoir ça
1 2 3 4
| <div attr="chapitre">
<div attr="article">...</div>
<div attr="article">...</div>
</div> |
j'ai ça
1 2 3 4
| <chapitre>
<article>...</article>
<article>...</article>
</chapitre> |
ce qui permet de désambiguïser mes </div> et de pouvoir matcher mes éléments de cette manière
$pattern="<chapitre>.*?</chapitre>"
mais ça marche pas. ça me renvoie toujours sur le
return "Pb d'imbrication pour la balise div\n";
bien que le fichier soit valide xhtml.
5 ) je suis sous mac OSX
6 ) quelqu'un a une idée / piste de comment je pourrais m'y prendre ?
je dois me pendre ? Y'a un module qui ferait ça ? Dois je plutot partir sur du XLS pour faire mes transformations ? Bref, vous l'aurez compris, je suis un peu perdu, excusez mon amateurisme.
Merci encore, si vous avez besoin de plus de précisions, n'hésitez pas ,)
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
|
use locale;
open(IN,"<","index.html");
while($line=<IN>){
$doc.=$line;
}
open(OUT,">","out.xml");
print OUT parseFirstTag($doc);
close(IN);close(OUT);
sub parseFirstTag {
my $text=shift;
if ($text=~/^(.*?)<div\s?[^>]*?><h\d><a[^>]*?>([^ ]*?) ([^<]*?)<\/a><\/h\d>(.*)/si) {
my $avantTag=$1; # on enregistre ce qui précède
my $type=$2;
my $id=$3;
my $apresTag=$4; # on enregistre ce qui suit
my $content="";
my $resteAFermer=1; # on enregistre le nombre de balises fermantes qu'il va falloir trouver dans la suite
# tant qu'il reste des balises fermantes </tag> à trouver
while ($resteAFermer>0) {
# on recherche dans la suite la première occurrence de balise fermante
if ($apresTag=~/^(.*?)(<\/div>)(.*)/i) {
my $avant=$1; # on enregistre ce qui précède cette fermante (dans la suite)
my $fermante=$2;
$content.=$avant.$fermante;
$apresTag=$3; # on met à jour la suite à analyser
my $compteOuvrantes=($avant=~/<div[^>]*>/gi); # on compte le nombre de balises ouvrantes présentes dans ce qui précède la fermante
$resteAFermer = $resteAFermer - 1 + $compteOuvrantes; # on met à jour le nombre de fermante à trouver dans la suite ( -1 car on vient d'en trouver une +compteOuvrante pour toutes celles qu'on vient d'ouvrir)
}
else {
# si on ne trouve pas de fermante, c'est qu'il y a un problème de codage xml
return "Pb d'imbrication pour la balise div\n";
$resteAFermer=-1; # on force la sortie
}
}
# si on est sorti de la boucle correctement, en trouvant la dernière fermante, on effectue la suppression en réaffectant $text
if ($resteAFermer==0) {
$content=~/^(.*)<\/div>$/;
$content=$1;
$text=$avantTag."<".$type." id=\"".$id."\">".$content."</".$type.">".$apresTag;
}
}
return $text;
} |
Puis pour les amateurs d'xkcd (et de segfault) comme moi :p
Partager