Ajouter une balise avec XSLT
C'est la version XSLT de cette page que j'avais faite à propos de sed.
J'avais donc des blocs de ce style :
<p>bidule</p> <ul> <li>foo</li> <li>baaaar</li> </ul>
Que je voulais transformer comme ça :
<div> <p>bidule</p> <ul> <li>foo</li> <li>baaaar</li> </ul> </div>
Pour pimenter l'exemple, je ne veux faire cette transformation que pour la première occurence de ce bloc à l'intérieur du <body>
. Pour ça, je dois utiliser [1]
comme ceci :
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes"/> <!-- le template "à l'identique" pour recopier tout tel quel --> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <!-- je suppose que le bloc que je cherche se trouve dans le body --> <xsl:template match="body"> <xsl:copy> <xsl:copy-of select="p[1]/preceding-sibling::*"/> <div> <xsl:copy-of select="p[1]|ul[1]"/> </div> <xsl:copy-of select="ul[1]/following-sibling::*"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
Ça se complique…
Une autre fois, j'ai eu besoin d'ajouter une balise <ul>
autour d'un lot de <li class="machin">
. Je ne pouvais pas savoir combien j'avais de <li>
mais ce n'est pas un problème pour XSLT
J'avais donc des blocs de ce style :
<ul> <li>foo</li> <li class="machin">bar</li> <li class="machin">truc</li> <li class="machin">bidule</li> <li>chose</li> </ul>
Que je voulais transformer comme ça :
<ul> <li>foo</li> <ul> <li class="machin">bar</li> <li class="machin">truc</li> <li class="machin">bidule</li> </ul> <li>chose</li> </ul>
Je ne sais pas si c'est la façon de faire la plus simple, mais elle fonctionne :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes"/> <xsl:template match="@*|node()" name="recopie-tout-tel-quel"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- on empêche le traitement "recopie tout tel quel" des li, sans quoi les li class="machin" seront dupliqués --> <xsl:template match="li" /> <!-- les li qui n'ont pas class="machin", on les laisse tels quels --> <xsl:template match="li[not(@class='machin')]"> <xsl:call-template name="recopie-tout-tel-quel"/> </xsl:template> <!-- quand on a un li class="machin" qui n'est pas précédé d'un li class="machin" --> <xsl:template match="li[@class='machin'][preceding-sibling::*[1][not(self::li[@class='machin'])]]"> <!-- ouvre le ul --> <ul> <!-- traite les li class="machin" avec un mode particulier --> <xsl:apply-templates select="self::li[@class='machin']" mode="copie"/> <!-- ferme le ul --> </ul> </xsl:template> <!-- le traitement particulier (avec un paramètre mode) appelé depuis le template ci-dessus --> <xsl:template match="li" mode="copie"> <!-- on met le li tel quel --> <xsl:call-template name="recopie-tout-tel-quel"/> <!-- puis on rappelle ce template particulier si l'élément suivant est un li class="machin" --> <xsl:apply-templates select="following-sibling::*[1][self::li[@class='machin']]" mode="copie"/> <!-- si l'élément suivant n'est pas un li class="machin", ce traitement s'arrête là --> </xsl:template> </xsl:stylesheet>