TD 11: XSLT

Rappels / Outils

Exercice : SVG

On travaille sur un fichier SVG (à gauche, son contenu; à droite son rendu; tel que vous le voyez en ouvrant le fichier .svg dans un navigateur Web):
<?xml version="1.0" standalone="no"?>
<svg width="700" height="560" version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  <desc>Four separate rectangles
  </desc>
  <rect x="20" y="20" width="370" height="272"/>
  <rect x="430" y="20" width="250" height="272"/>
  <rect x="20" y="332" width="370" height="208"/>
  <rect x="430" y="332" width="250" height="208"/>

  <!-- Show outline of canvas using 'rect' element -->
  <rect x="1" y="1" width="698" height="558"
        fill="none" stroke="blue" stroke-width="2" />
</svg>
      
  1. Écrire une stylesheet XSLT qui, appliquée au fichier 2.svg, donne le nombre de rectangles.
    Aides:
    Exemple de sortie souhaitée: Nombre de rectangles: 5

    RENDU: 2.1.xsl


  2. Modifiez votre XSLT pour afficher également les aires de tous les rectangles d'un fichier SVG, dans l'ordre où ils apparaissent. Attention, l'exemple ne contient que des rectangles se situant à la "racine" du SVG, mais votre code devra marcher quelque soit la position des rectangles dans la hierarchie XML.
    Exemple de sortie souhaitée:
    Nombre de rectangles: 5
    Aires des rectangles:
    100640 pixels
    68000 pixels
    76960 pixels
    52000 pixels
    389484 pixels
    

    RENDU: 2.2.xsl


  3. Modifiez votre XSLT pour qu'il ne prenne en compte que les rectanges remplis (regarder l'attribut fill), et qu'il calcule les aires en pourcentage de la surface totale.
    Exemple de sortie souhaitée:
    Nombre de rectangles: 4
    Aires des rectangles:
    25.6734693877551 %
    17.3469387755102 %
    19.6326530612245 %
    13.265306122449 %
    

    RENDU: 2.3.xsl


  4. Créez un XSLT qui transforme notre SVG, et tout SVG contenant des rectangles, en le même SVG "réduit" de 50% (les dimensions de l'image et des rectangles).
    Aides:
    Appliquez ce XSLT au fichier 2.svg: xsltproc votre.xsl 2.svg > 2.4.svg, et ouvrez la sortie 2.4.svg dans votre navigateur.
    Réparez votre XSLT jusqu'à ce que ça marche!

    RENDU: 2.4.xsl


  5. Créer un XSLT qui transforme 2.svg en remplaçant chaque rectangle rempli par une copie réduite du document SVG originel (correspondant à la taille du rectangle remplacé).
    Ça devrait ressembler a l'image ci-dessous:


    Comme indiqué dans le deuxième point des "Aides" du 2.4, faites-vous plaisir avec <g transform="...">.

    RENDU: 2.5.xsl


  6. Modifiez, si besoin, le XSLT pour qu'il puisse s'appliquer récursivement.
    Note: l'idée est qu'en appliquant la transformation K fois, on obtiendra N2K rectangles, où N est le nombre de rectangles dans l'image originelle (donc ici, en appliquant 3 fois avec 4 rectangles, on obtient 423 = 48 = 65536 rectangles!!). En effet, chaque transformation élève le nombre de rectangles au carré.

    Appliquez-le 1, 2 puis 3 fois:
    xsltproc votre.xsl 2.svg > 2.6.svg
    xsltproc votre.xsl 2.6.svg > 2.66.svg
    xsltproc votre.xsl 2.66.svg > 2.666.svg
    
    Attention: Le dernier, 2.666.svg, peut être trop difficile à ouvrir avec votre navigateur; essayer plutôt de le convertir en .png avec convert:
    convert 2.666.svg 2.666.png
    Vous pourrez ensuite facilement ouvrir et visualiser 2.666.png. Et vérifiez que ça ressemble à ça:

    RENDU: 2.6.xsl


  7. (*) En s'aidant du graphique ci-contre (cliquer pour l'agrandir), créer un XSLT qui permet, en l'appliquant récursivement, de transformer toute image SVG de proportions 200x450 en fougère de Barnsley.

    Pour ajuster vos transformations, utilisez le fichier 2.7.svg: xsltproc votre.xsl 2.7.svg > test.svg.
    Une fois ajusté; appliquez-le 10 fois de suite sur 2.7.0.svg à l'aide de cette commande (copiez-collez tout dans votre terminal):
    XSL=votre.xsl
    for i in {0..10}; do
      echo "Iteration #$i"
      (( j=i+1 ))
      xsltproc $XSL 2.7.$i.svg > 2.7.$j.svg
      j=$i
    done
    
    Vous pouvez également essayer avec d'autres images 200x450, comme Hello Kitty (en le sauvegardant sous 2.7.0.svg, le script marchera sans modifications).
    Ca devrait ressembler à ça:

    RENDU: 2.7.xsl