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
Code html : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 <div attr="chapitre"> <div attr="article">...</div> <div attr="article">...</div> </div>
j'ai ça
ce qui permet de désambiguïser mes </div> et de pouvoir matcher mes éléments de cette manière
Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 <chapitre> <article>...</article> <article>...</article> </chapitre>
Code perl : Sélectionner tout - Visualiser dans une fenêtre à part $pattern="<chapitre>.*?</chapitre>"
mais ça marche pas. ça me renvoie toujours sur lebien que le fichier soit valide xhtml.
Code perl : Sélectionner tout - Visualiser dans une fenêtre à part return "Pb d'imbrication pour la balise div\n";
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 ,)
Code perl : 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
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