Transformer un document XML en SVG avec XSLT
Techniques
Cette section permet de regrouper un ensemble de techniques ou de scripts qui ont l'originalité d'arriver à résoudre une difficulté avec le moindre effort ou qui sont particulièrement efficaces...
Techniques / Transformer un document XML en SVG avec XSLT
- Transformation d'un document XML à la volée avec MSXML :
La technique XML est trés avantageuse car elle permet de disposer d'une source de données complètement indépendante de la représentation qu'on pourra leur donner. Utilisé conjointement avec XSLT nous pouvons ainsi transformer une fichier XML en des sorties variées et adaptées au média visé comme le format (X)HTML, PDF, RTF, SVG, SMIL...
Dans cet article je vais essayer de vous montrer un exemple simple de transformation d'un document XML en graphique SVG en opérant une transformation depuis ASP. La rédaction d'un fichier XML,XSL,SVG est sensée être connue. ( Des cours adéquats seront bientôt créés à cet effet.)
C'est la dll MSXML qui nous permettra d'opérer la transformation à la volée. Le graphique généré sera ensuite directement affichable sur le poste client grâce au plug-in ADOBE SVG Viewer disponible à cette adresse : http://www.adobe.com/svg/viewer/install/main.html. Le langage SVG est lui même une grammaire XML permettant la représentation de graphiques vectoriels plus ou moins complexes. Vous pouvez d'ailleurs voir par vous même les différentes possibilités offertes par ce langage grâce à DypsoSVGPie.
- Le fichier XML source :
Celui-ci pourra bien évidemment provenir d'une base de données, être stocké dans le système de fichier ou provenir d'un flux depuis un site externe ... Dans notre cas précis, il sera enregistré sur le disque du serveur pour des raisons de simplifications.
Sales.xml
<?xml version="1.0" encoding="iso-8859-1" ?> <Sales> <Report Year="2002"> <Summary Region="North"> <Q1 TotalSales="10" /> <Q2 TotalSales="150" /> <Q3 TotalSales="140" /> <Q4 TotalSales="180" /> </Summary> <Summary Region="East"> <Q1 TotalSales="110" /> <Q2 TotalSales="70" /> <Q3 TotalSales="100" /> <Q4 TotalSales="50" /> </Summary> <Summary Region="West"> <Q1 TotalSales="60" /> <Q2 TotalSales="140" /> <Q3 TotalSales="130" /> <Q4 TotalSales="200" /> </Summary> <Summary Region="South"> <Q1 TotalSales="100" /> <Q2 TotalSales="140" /> <Q3 TotalSales="80" /> <Q4 TotalSales="95" /> </Summary> </Report> </Sales>
- Le fichier XSL :
De même celui-ci, est normalement stocké au même endroit :
Sales.xsl
<?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" media-type="image/svg+xml" encoding="iso-8859-1" indent="yes" /> <xsl:strip-space elements="*" /> <xsl:template match="/"> <svg width="14cm" height="10cm" xmlns="http://www.w3.org/2000/svg"> <!--Heading--> <text x="5" y="28" text-anchor="left" font-weight="bolder" font-size="20" fill="maroon" text-decoration="underline"> Sales Report for DP & Co. Year <xsl:value-of select="/Sales/Report/@Year"/> </text> <!--Caption (Vertical)--> <g transform="translate(40, 100) rotate(270, 0, 0)"> <text x="-98" y="5" text-anchor="middle" font-weight="bolder" font-size="16" fill="black"> Sales (Hundred Thousand USD) </text> </g> <!--Caption (Horizontal)--> <text x="190" y="350" font-size="16" font-weight="bolder" fill="black"> Region (Per Quarter) </text> <!--Lines--> <g stroke="gray" stroke-width="1"> <line x1="70" y1="300" x2="490" y2="300"/> <line x1="70" y1="300" x2="70" y2="70"/> </g> <!--Data Charts--> <xsl:call-template name="drawSalesBars"> <xsl:with-param name="Region" select="string('North')"/> <xsl:with-param name="barColor" select="string('#B8CCDE')"/> <xsl:with-param name="startXPosition" select="80"/> </xsl:call-template> <xsl:call-template name="drawSalesBars"> <xsl:with-param name="Region" select="string('East')"/> <xsl:with-param name="barColor" select="string('#FFFFCC')"/> <xsl:with-param name="startXPosition" select="180"/> </xsl:call-template> <xsl:call-template name="drawSalesBars"> <xsl:with-param name="Region" select="string('West')"/> <xsl:with-param name="barColor" select="string('#9999FF')"/> <xsl:with-param name="startXPosition" select="280"/> </xsl:call-template> <xsl:call-template name="drawSalesBars"> <xsl:with-param name="Region" select="string('South')"/> <xsl:with-param name="barColor" select="string('#993366')"/> <xsl:with-param name="startXPosition" select="380"/> </xsl:call-template> </svg> </xsl:template> <xsl:template name="drawSalesBars" xmlns="http://www.w3.org/2000/svg"> <xsl:param name="Region"/> <xsl:param name="barColor"/> <xsl:param name="startXPosition"/> <text x="{$startXPosition+10}" y="320" font-weight="bolder" font-size="16" fill="#225C91"> <xsl:value-of select="$Region" /> </text> <xsl:variable name="q1SalesAmt" select="/Sales/Report/Summary[@Region=$Region]/ Q1/@TotalSales"/> <xsl:variable name="q1YPos" select="300 - $q1SalesAmt" /> <rect stroke-width="1" stroke="black" width="15" fill="{$barColor}" x="{$startXPosition}" y="{$q1YPos}" height="{$q1SalesAmt}"/> <text x="{$startXPosition}" y="{$q1YPos - 5}" font-size="11" fill="black"><xsl:value-of select="$q1SalesAmt"/></text> <xsl:variable name="q2SalesAmt" select="/Sales/Report/Summary[@Region=$Region]/ Q2/@TotalSales"/> <xsl:variable name="q2YPos" select="300 - $q2SalesAmt" /> <rect stroke-width="1" stroke="black" width="15" fill="{$barColor}" x="{$startXPosition + 20}" y="{$q2YPos}" height="{$q2SalesAmt}"/> <text x="{$startXPosition + 20}" y="{$q2YPos - 5}" font-size="11" fill="black"><xsl:value-of select="$q2SalesAmt"/> </text> <xsl:variable name="q3SalesAmt" select="/Sales/Report/Summary[@Region=$Region]/ Q3/@TotalSales" /> <xsl:variable name="q3YPos" select="300 - $q3SalesAmt" /> <rect stroke-width="1" stroke="black" width="15" fill="{$barColor}" x="{$startXPosition + 40}" y="{$q3YPos}" height="{$q3SalesAmt}"/> <text x="{$startXPosition + 40}" y="{$q3YPos - 5}" font-size="11" fill="black"><xsl:value-of select="$q3SalesAmt"/> </text> <xsl:variable name="q4SalesAmt" select="/Sales/Report/Summary[@Region=$Region]/ Q4/@TotalSales"/> <xsl:variable name="q4YPos" select="300 - $q4SalesAmt" /> <rect stroke-width="1" stroke="black" width="15" fill="{$barColor}" x="{$startXPosition + 60}" y="{$q4YPos}" height="{$q4SalesAmt}"/> <text x="{$startXPosition + 60}" y="{$q4YPos - 5}" font-size="11" fill="black"><xsl:value-of select="$q4SalesAmt"/> </text> </xsl:template> </xsl:stylesheet>
- Le fichier ASP :
Les fichiers sources et de transformation étant créés nous pouvoins enfin nous pencher sur le fichier ASP :
Sales.asp
<% response.buffer = true set xml = Server.CreateObject("Microsoft.XMLDOM") xml.async = false xml.load(Server.MapPath("sales.xml")) set xsl = Server.CreateObject("Microsoft.XMLDOM") xsl.async = false xsl.load(Server.MapPath("sales.xsl")) response.Charset="iso-8859-1" response.contenttype = "image/svg+xml" xml.transformNodeToObject xsl,Response %>
Afin de tranformer le fichier XML en SVG, c'est la méthode transformNodeToObject que j'ai employé au lieu de transformNode qui nous contraindrait à toujours garder l'encodage UTF-16 et ce malgré la mention <xsl:output encoding="..."/> utilisée. La méthode transformNodeToObject nous permet de générer un objet Stream qui ne nous pose aucun problème d'encodage et que nous pouvons donc renvoyer vers l'objet Response afin de permettre la sortie du SVG sur le poste client.
Warning: mysql_connect() [function.mysql-connect]: Access denied for user 'dypso'@'172.20.245.55' (using password: YES) in /mnt/110/sdb/3/1/dypso/include/tools.php on line 106
Impossible de se connecter : Access denied for user 'dypso'@'172.20.245.55' (using password: YES)