Double Itérateur

Je travaille à nouveau sur des codes, cette fois à partir du XML de la base Legi. Je vais mettre ici plusieurs morceaux du code. Aujourd’hui voici un exemple d’un patern de programmation que j’utilise beaucoup ces temps-ci, les itérateurs, ici dans une variante à double profondeur. A la base je récupère une liste d’éléments sans volume, des titres de niveaux variables et des articles de code. Il arrive que certaines branches de l’arborescence de titre soient vides car les articles qu’elles contenaient ont été abrogés. Une approche aurait consisté de donner du volume à cette cette liste de titres en fonction de leurs niveaux d’importance mais cela aurait été inutile car le but est ensuite de générer des PDF avec FOP et des EPubs avec perl. Bref, il faut supprimer certains titres car ils sont inutiles selon mes critères de droit positif.

$d est mon document vu en perl par XML::LibXML.
$root = $dom->getDocumentElement();
(@nodes) = $root->childNodes();
while ($node = shift(@nodes)) {
#iterateur principal
if ($node->nodeType ==3) {
#Si c’est une node de texte je la supprime si elle ne contient pas de texte
$node->parentNode->removeChild($node) unless($node->textContent =~ /\[\w\-]/);
} else {
if ($node->nodeName =~ /^h(\d)/) {
#Si c’est un titre, j’en inspecte le niveau hiérarchique.
$level = $1;
my @charette;
#Je prépare une charette dans laquel je mettrai l’hypothétique lot à supprimer si effectivement le soul arbre ne contient pas d’articles.
my @copie = @nodes
#Je fais une copie de mon nodeset pour itérer dans ses sous branches.
while ($cand = shift(@node)) {
#Itérateur secondaire
$ca = $cand->nodeName;
last() if ($ca eq ‘article’);
#Je sors de l’itérateur si un des enfants est un article
if (($ca =~ /hash(\d)/) and ($1 > $level)) {
#Si c’est un sous branche je l’inscrit à la charette sans la supprimer.
push(@charette,$cand);
}
if (($ca =~ /hash(\d)/) and ($1 <= $level)) {
#Si c’est un titre de niveau égal ou supérieur, je vide la charette je supprime les nodes
map {
$_->parentNode->removeChild($_);
} @charette;
$node->parentNode->removeChild($node);
}
}
}
}
}

Pas si compliqué que cela, j’ai juste longtemps hésité sur la copie.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *