Document

Emploi

La fonction document() permet de gérer au sein d'une même feuille plusieurs fichiers sources. Cette fonction mériterait à elle seule l'écriture d'un chapitre. Voici quelques exemples qui illustrent son efficacité.

Exemple : bilan de ventes

Nous voulons faire un bilan des ventes. Chaque vente donne lieu a un rapport dans un fichier séparé. En voici un exemple : vente.

1

Créer tout d'abord une feuille de style permettant de visualiser chaque vente.

sortie html
Nous devrons utiliser les fonctions récursives.
récursivité : Aide

1

A partir du document maître, modifier la feuille de style précédente pour visualiser chaque vente à la suite.

sortie htm

1

Etudier la feuille de style pour regrouper les ventes pour chaque état.
 la feuille de stylesortie htm


debut
Sum

Emploi

La fonction sum calcule la somme d'un ensemble de valeurs numériques situées dans un ensemble de noeuds.

select="sum($matches[team=current()]/team/@score)"
1

Calculer la somme des miles volés et gagnés durant une année.

Remarques importantes

Les valeurs à sommer doivent être explicitement présentes comme noeuds du document et numériques.
Nous devrons dans le cas contraire traiter l'ensemble de noeuds à l'aide d'un modèle récursif.

Sortie HTML

exemple

<items>
    <item part_no="28392-33-TT">
      <name>Turnip Twaddler</name>
      <qty>3</qty>
      <price>10</price>
    </item>
    <item part_no="28813-70-PG">
      <name>Prawn Goader</name>
      <qty>1</qty>
      <price>18</price>
    </item>

<xsl:value-of select="sum(//item/qty)" />   donnerait 4

<xsl:value-of select="sum(//item/price * //item/qty)" /> 
ERROR: Description: Argument 1 must return a node-set.
-->sum(//item/price * //item/qty)<--
1

Présenter sous forme de tableau le résultat d'une compétition.
Créer deux variables globales teams et Matches regroupant tous les éléments, les précédents de même valeur exclus.
Pour chaque équipe on calculera le nombre de matchs joués, gagnés, perdus.
"Allez les petits"
utiliser la fonction count(aide : exclusion des précédents communs)

sortie html

debut
contains substring-after substring-before

Nous allons traiter un exemple utilisant les fonctions contains, substring-(afer,before). Ces fonctions classiques sont très utiles pour le changement de mots dans un texte.

Nous allons revenir sur les différentes définitions des fonctions.

Contains

La fonctions contains() renvoie true si une valeur textuelle contient une autre valeur.
test="contains($text, $replace)"
test=True si dans la variable text la valeur textuelle de la variable replace existe.

Substring-after substring-before

La fonction substring- divise une chaîne contenant des délimiteurs.

substring-before(le mot a trouver, 'a') renvoie le mot.

substring-after(le mot a trouver, 'a') renvoie trouver.

Ainsi, la combinaison suivante : substring-before($text, ancien_mot)+nouveau_mot+substring-after($text, ancien_mot) remplacerait dans un texte l'ancien_mot par le nouveau_mot.

1

Nous allons tenter de remplacer toutes les occurrences du mot dans un texte.

La difficulté majeure n'est pas l'utilisation des fonctions substring-* mais la mise en place de la récursivité pour traiter l'ensemble des mots à remplacer.
On utilisera deux variables remplace et by pour indiquer les valeurs des chaînes à remplacer.

Ecrire un modèle qui effectue directement le premier remplacement, puis s'appelle  lui même de façon récursise pour remplacer les occurrences dans le reste du texte non encore traiter.
Pensez à définir le test de Fin de récursivité.

La sortie montre le texte où Evry a remplacé frauduleusement Westminster !

Sortie XML

debut
Position

Emploi

La fonction position renvoie la valeur de la position contextuelle.

<xsl:if test="position()!=last()">, </xsl:if>
1

La feuille de style devra mettre en forme une liste. Les éléments seront mis dans un tableau. Trois couleurs de lignes se répéteront.

Remarque

le test suivant trouve si le numéro d'une ligne d'un tableau est pair :
if (numéro mod 2 = 0) then "pair"

sortie html

debut
Last

Emploi

La fonction last renvoie la valeur de la taille contextuelle. Last donne le nombre affecté au dernier de la liste de noeud.

<xsl:if test="position()!=last()">, </xsl:if>
1

La feuille de style devra mettre en forme une liste de noms.

Remarque

on utilisera <xsl:choose>

sortie html

debut
Concat

Emploi

La fonction concat permet de construire une chaîne à partir de plusieurs éléments convertis en chaîne et concaténés.

concat('Paris',' est la capitale de la ','France) = Paris est la capitale de la france
1

La feuille de style devra parcourir tous les éléments en utilisant la fonction concat() pour obtenir les sorties selon le format <city> name, country </city>

remarque

la fonction concat est une alternative à l'écriture de :
<xsl:value-of select="name"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="country"/>sortie xml

debut
Count

Emploi

La fonction count compte le nombre de noeuds de l'ensemble de noeuds quelle reçoit. L'exemple suivant affecte à une variable le nombre d'attributs du noeud courant :

<xsl:variable name="nombre-attributs" select="count(@*)"/>


1

La feuille de style devra dénombrer les valeurs distinctes de l'attribut country de la liste d'élément <city>.
La réalisation de la feuille est en deux étapes
- Construction de l'ensemble de noeuds contenant tout élément <city> dont l'attribut country diffère de toute <city> précédente
- Dénombrer les noeuds de cet ensemble

Aide

La première étape n'est pas simple, on utilisera le type d'écriture : select="//SPEAKER[not(.=preceding::SPEAKER)]"sortie xml

debut
Generate-id

Cette fonction génère une chaîne, sous la forme d'un nom unique XML, identifiant de façon unique un noeud.

Emploi-1

La fonction generate-id() est très souvent utilisée dans la création de liens dans un document de sortie.

Création des ancres :
<a href="#{generate-id(artist)}"> <xsl:value-of select="artist" /> </a>
Création des liens :
<a name="{generate-id(artist)}"> <xsl:value-of select="artist" /> </a>
1
La feuille de style devra énumérer les hôtels avec un lien vers le détail du lieu concerné.

Il est capital de bien comprendre que les id générés n'ayant aucune ressemblance avec toute valeur d'attribut ID du document, les nœuds ne peuvent être trouvés à l'aide de la fonction id().
sortie html

Emploi-2

La second utilisation de la fonction generate-id() est de comparer des nœuds, afin de savoir s'ils sont identiques.

Comme les clés proposent un moyen efficace de récupérer tous les nœuds partageant une certaine valeur, elles sont utiles lorsque l'on doit regrouper dans une sortie des nœuds possédant une valeur commune.

<xsl:for-each select="//year[not(.=preceding::year)]">
<xsl:sort select="." />
    <xsl:variable name="annee" select="." />
    <h1> album : <xsl:value-of select="$annee"/> </h1>
    <xsl:for-each select="//cd[year=$annee]">
         <p>Title: <xsl:value-of select="title" /> </p>
  </xsl:for-each>
</xsl:for-each>

debut
key

Emploi-1

La fonction key identifie les noeuds à partir d'une valeur donnée de la clé nommée. Elle permet d'effectuer des accès associatifs (par le contenu) à des noeuds. Elle est utilisée de pair avec <xsl:key>.

<xsl:key name="livre-auteur" match="livre" use="auteur"/>
<xsl:for-each select="key('livre-auteur','dupont');/>
1
L'exemple  suivant utilise deux fichiers source. Le premier contient la liste de livre et le deuxième contient la bibliographie des auteurs.

Lorsque nous disposons de deux documents sources, la valeur d'un élément peut servir de référence croisée vers le deuxième fichier (comme une jointure en SQL). Déclarer une clé identifiant les éléments <author> d'après les attributs de nom. Le fichier source secondaire est référencé par une variable globale.

1
Puisque la fonction key ne recherche que dans le document contenant le noeud contextuel, on utilisera pour le changement de contexte <xsl:for-each>.
sortie html

Emploi-2

Une autre utilisation des clés permet de regrouper des noeuds apparentés.
On définit une clé sur la valeur commune déterminant l'appartenance au groupe. Par exemple, si chaque année des CDs composent un groupe, la définition de la clé sera :

  <xsl:key name="annee-gr" match="cd" use="year" />

La boucle externe sélectionne un cd pour chaque année. Pour cela on sélectionne tous les CDs que l'on filtre en ne sélectionnant que les premiers de chaque année.
On peut dire qu'un cd est le premier de l'année en le comparant au premier nœud de l'ensemble de nœuds renvoyé par la fonction key() appliquée à cette année.

<xsl:for-each select="//cd[generate-id()=generate-id(key (' annee-gr',year)[1])]">

On utilise ici le prédicat generate-id() afin de vérifier que l'année est le même nœud que celui renvoyé par la fonction key().

<xsl:key name="annee-gr" match="cd" use="year" /> 
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="//cd[generate-id()= generate-id(key('annee-gr',year)[1])]">
    <h1> album :  <xsl:value-of select="year" /> </h1>
    <xsl:for-each select="key('annee-groupe',year)">
        <p>Title: <xsl:value-of select="title" />
      </xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>

1
On va appliquer ce principe sur un exemple en créant les deux boucles.
L'idée est de regrouper les villes par pays.
La boucle externe sélectionne une ville par pays. la façon d'y parvenir consiste à sélectionner toutes les villes, puis de filtrer celles qui ne sont pas la  première du pays.
La première ville sera celle qui correspond au premier noeud de l'ensemble de noeuds renvoyé par la fonction key() appliquée à ce pays.
fichier de sortie

debut

Rappel : la récurcivité