Ok, je suis arrivé à le faire, mais je confirme, c'était pas évident du tout.
Première précision : je ne connais que XSLT 1.0 et xPath 1.0. Pas de XSLT 2.0 et je ne connais pas bien EXSLT non plus. Tout ce petit monde pourrait peut-être simplifier un peu les choses.
Je confirme que le problème ressemble à un regroupement Muench, mais l'ennui, c'est, on regroupe sur quoi ?
On veut regrouper, d'une part sur la @class, d'autre part sur quelle "séquence" de cette @class se trouve le nœud.
Or, ça si on comprend grosso-modo ce que ça veut dire, l'exprimer en xPath 1.0 n'a même pas l'air possible.
Comment j'ai fait : sans clé.
Pour commencer j'ai fait un template nommé qui calcule, pour le nœud en cours, dans quelle séquence de sa @class il se trouve (première séquence, deuxième séquence, etc.)
Ça donne ça :
1 2 3 4 5 6 7 8 9
| <xsl:template name="seqNum">
<xsl:value-of select="count(
(preceding-sibling::*|self::*)[
@class = current()/@class
and
not(preceding-sibling::*[1][@class = current()/@class])
]
)"/>
</xsl:template> |
En appelant ce template, on obtient le numéro de la séquence dans laquelle est le nœud en cours.
Reste à s'en servir.
#1 Sur quoi boucler ? J'ai fait un for-each sur tous les <contenu>.
À l'intérieur de ce for-each, je ne fais quelque chose que si le <contenu> en cours répond à des conditions.
Ce qu'il y aurait à faire, c'est créer le <class name="{@class}"> ... </class> en mettant ce qu'il faut à l'intérieur.
Dans quel cas on a besoin de faire ça ? Quand on commence une nouvelle séquence, donc quand le nœud en cours n'a pas de voisin précédent de la même classe que lui :
<xsl:if test="not(preceding-sibling::*[1][@class = current()/@class])">
#2 comment sélectionner ce qu'on va mettre dans ce <class> ?
- D'abord le nœud pour qui on l'a ouvert.
- Ensuite les nœuds de même @class et qui sont dans la même séquence.
=> On calcule, avec le template, le numéro de séquence du nœud qui a ouvert ce <class>
=> On fait un for-each sur tous les nœuds suivant de même @class que lui.
=> Pour chacun, on calcule aussi son numéro de séquence.
=> Si c'est le même, on ajoute le nœud.
Conclusion : regroupement effectué. Reste à calculer tes class="1", pas trop difficile normalement.
Partager