UP PREVIOUS NEXT   Technologies Internet et Education, © TECFA
  2. Génération de SVG avec XSLT

2. Génération de SVG avec XSLT

2.1 Traitement batch ou server-side

Solution 1: Fabrication de travaux.svg avec un processeur XSLT:

saxon -o travaux.svg travaux.xml travaux.xsl

Solution 2: XSLT avec un service de traduction en ligne:

Solution 3: XSLT server-side avec PHP:

<?php
header("Content-type: image/svg+xml")
;

 

Code PHP pour la solution 3

header("Content-type: image/svg+xml");
 
error_reporting(E_ALL);
 
$xml_file = 'travaux.xml';
$xsl_file = 'travaux.xsl';
 
// load the xml file (and test first if it exists)
$dom_object = new DomDocument();
if (!file_exists($xml_file)) exit('Failed to open $xml_file');
$dom_object->load($xml_file);
 
// create dom object for the XSL stylesheet and configure the transformer
$xsl_obj = new DomDocument();
if (!file_exists($xsl_file)) exit('Failed to open $xsl_file');
$xsl_obj->load($xsl_file);
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl_obj); // attach the xsl rules
 
$html_fragment = $proc->transformToXML($dom_object);
print ($html_fragment); 

Exemple 2-1: Simple visualisation d'une page travaux

Afficher travaux.xml (avec FireFox !) ou travaux.svg et lire ci-dessous

Code XSLT: travaux.xsl

  • Ici on utilisera un style de programmation fonctionnelle
    • Donc pas le mécanisme habituel d'exécution de règles
    • Cela nous permettra de positionner plus facilement les éléments sur l'écran.
  • Pour mieux comprendre comment cela marche:
    • commencez à lire la documentation de ce code depuis la fin (<xsl:template match="student">)
    • Tracez l'exécution du programme avec un processeur xslt comme saxon.
 
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
  • Ces déclarations indiquent qu'on produira du SVG
 <xsl:output method="xml" indent="yes" 
  encoding="ISO-8859-1"
  standalone="no"
  doctype-public="-//W3C//DTD SVG 1.0//EN" 
  doctype-system="http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" />
  • Ci-dessous on déclare des paramètres globaux pour définir qq. distances.
    Vous pouvez les modifier pour voir leur effet
 <!-- GLOBAL PARAMETERS - you may change this -->
 
 <xsl:param name="increase-y" select="60"/>
 <xsl:param name="element-length" select="150"/>
 <xsl:param name="element-height" select="30"/>
 <xsl:param name="space" select="10"/>
 
 <!-- XSLT Functions -->
  • Le template ci-dessous affichera chaque exercice
    • tous les exercices d'un cours sont affichés sur une même ligne, décalés vers la droite
    • le contexte d'exécution est l'élément "exercise".
 <!-- Display a single exercise -->
 <xsl:template name="render-exercise">
  <xsl:param name="position-x"/>
  <xsl:param name="position-y"/>
 
  <rect x="{$position-x * ( $element-length + $space ) }" 
        y="{$position-y * $increase-y }" 
        width="{$element-length}" 
        height="{$element-height}"
        style="fill:yellow; stroke:black; stroke-width:3"/>
 
  <text x="{$position-x * ( $element-length + $space ) }" 
        y="{$position-y * $increase-y + 15 }"
        style="stroke:#000099;fill:#000099;font-size:10;">
   <xsl:value-of select="title"/>
 
  </text>
 </xsl:template>
 
 <!-- Display a course (Text + each exercise a box on the same line  -->
  • Render-course est un template qui a pour boulot d'afficher les éléments "exercice"
    • Le contexte d'exécution est l'élément "course"
    • En fonction de sa position dans la liste, cet élément est affiché un peu plus bas ($position-y)
    • On affiche le titre du cours plus tous les exercices associés, mais pour cela on utilise de nouveau un autre template
 <xsl:template name="render-course">
  <xsl:param name="position-y"/>
 
  <text x="{$space}" y="{$position-y * $increase-y - $space }
"  
        style="stroke:#000099;fill:#000099;font-size:12;">
   <xsl:value-of select="title"/>
  </text>
 
  <xsl:for-each select="exercise">
   <xsl:call-template name="render-exercise">
    <xsl:with-param name="position-x" select="position()"/>
    <xsl:with-param name="position-y" select="$position-y"/>
   </xsl:call-template>
  </xsl:for-each>
  
 </xsl:template>
  
  • Ce template est appelé en premier en tant que règle.
    • Il contient une boucle qui, pour chaque élément-enfant "course", fait appel au template "render-course" en lui passant le contexte de l'élément "course" en question plus sa position dans la liste des enfants (select="position")
 <xsl:template match="student">
  
  <svg width="1000" height="900">
   <!-- xmlns="http://www.w3.org/2000/svg"> -->
   <text x="{$space}" y="90" style="stroke:#000099;fill:#000099;font-size:24;">
    Example visualisation of a student's work page</text>
   
   <svg y="3cm">
    <xsl:for-each select="//course">
     <xsl:call-template name="render-course">
       <xsl:with-param name="position-y" select="position()
"/>
     </xsl:call-template>
    </xsl:for-each>
   </svg>
 
  </svg>
  
 </xsl:template>
</xsl:stylesheet>

2.2 SVG avec XSLT client-side

A. Solution qui marche dans Firefox avec SVG natif (Firefox 1.5)

Exemple 2-2: Visualisation client-side avec un navigateur SVG natif

<xsl:template match="/">
  <html xmlns:svg="http://www.w3.org/2000/svg">     
   <head><title>Client-side XHTML / SVG generation</title></head>
   <body>
    <p> .....   </p>
   <svg width="1000" height="900" xmlns="http://www.w3.org/2000/svg">
     <text x="{$space}" y="90" style="stroke:#000099;fill:#000099;font-size:24;">Example visualisation of a student's work page</text>
     <svg y="3cm">
       <xsl:for-each select="//course">
         <xsl:call-template name="render-course">
           <xsl:with-param name="position-y" select="position()"/>
         </xsl:call-template>
       </xsl:for-each>
     </svg>  
    </svg>  
   </body> 
</html> 
</xsl:template>

Solution qui marche aussi avec un plugin SVG et IE 6

<html xmlns:svg="http://www.w3.org/2000/svg">

Voici le template pour la racine:

<xsl:template match="/">
  <html xmlns:svg="http://www.w3.org/2000/svg">     
  <object id="AdobeSVG" CLASSID="clsid:78156a80-c6a1-4bbf-8e6a-3cd390eeb4e2"> </object>
   <xsl:processing-instruction name="import">namespace="svg" implementation="#AdobeSVG"</xsl:processing-instruction> 
 
   <head><title>Client-side XHTML / SVG generation</title></head>
 
   <body>
    <p> Read this article:
     <a href="http://surguy.net/articles/client-side-svg.xml">http://surguy.net/articles/client-side-svg.xml</a>.
     It explains how to generate SVG plugin code within XHTML.
   </p>
 
   <svg:svg width="1000" height="900" xmlns:svg="http://www.w3.org/2000/svg">
     <svg:text x="{$space}" y="90" style="stroke:#000099;fill:#000099;font-size:24;">Example visualisation of a student's work page</svg:text>
     <svg:svg y="3cm">
       <xsl:for-each select="//course">
         <xsl:call-template name="render-course">
           <xsl:with-param name="position-y" select="position()"/>
         </xsl:call-template>
       </xsl:for-each>
     </svg:svg>
   </svg:svg>
 </body>
</html>
</xsl:template>

UP PREVIOUS NEXT -- TIE