|
|
You need to install an XSLT processor on your machine so that you can apply XSL stylesheets to XML documents. If you haven't already done so, copy the Instant Saxon executable on the CD-ROM to a convenient directory on your PC and then add this directory to your PATH variable. An example of invoking this executable is given below:
saxon abc.xml abc.xsl >abc.svg
The preceding invocation applies the XSL stylesheet abc.xsl to the XML document abc.xml and then redirects the output to the file abc.svg.
If you want to see the list of options that you can use with saxon, you can type the following,
saxon -?
and you will see something like this:
No source file name SAXON 6.2.2 from Michael Kay Usage: saxon [options] source-doc style-doc {param=value}... Options: -a Use xml-stylesheet PI, not style-doc argument -ds Use standard tree data structure -dt Use tinytree data structure (default) -o filename Send output to named file or directory -m classname Use specified Emitter class for xsl:message output -r classname Use specified URIResolver class -t Display version and timing information -T Set standard TraceListener -TL classname Set a specific TraceListener -u Names are URLs not filenames -w0 Recover silently from recoverable errors -w1 Report recoverable errors and continue (default) -w2 Treat recoverable errors as fatal -x classname Use specified SAX parser for source file -y classname Use specified SAX parser for stylesheet -? Display this message
XSLT is an extremely powerful tool that can require a substantial amount of time and effort to gain a high level of mastery. With that in mind, let's start with a relatively easy example of an XML file containing a set of object tags that we can 'map' to an SVG document by means of an XSL stylesheet. Listing 17.13 contains the sample XML document xsltToSVG1.xml, which specifies a rectangle, a polygon, and an ellipse by way of standard XML tags; Listing 17.14 contains the XSL stylesheet xsltToSVG1.xsl that can be applied to xsltToSVG1.xml in order to generate an SVG document.
Listing 17.13 xsltToSVG1.xml
<?xml version="1.0"?> <objects> <object> <type>rect</type> <x>50</x> <y>50</y> <width>100</width> <height>50</height> <style>fill:red</style> </object> <object> <type>polygon</type> <points>300,50 450,50 350,100 300,150</points> <style>fill:blue</style> </object> <object> <type>ellipse</type> <cx>300</cx> <cy>100</cy> <rx>100</rx> <ry>50</ry> <style>fill:blue</style> </object> </objects>
The first point to observe in Listing 17.13 is the objects tag and the object tag; these were chosen in an arbitrary manner as a generic mechanism for including multiple SVG-like elements. In this particular case, Listing 17.13 contains the necessary attributes for specifying three SVG elements: a rectangle, a polygon, and an ellipse.
Listing 17.14 xsltToSVG1.xsl
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <svg> <g> <xsl:apply-templates/> </g> </svg> </xsl:template> <xsl:template match="objects/object"> <xsl:for-each select="."> <xsl:choose> <xsl:when test="./type = 'rect'"> <xsl:call-template name="createRectangle"/> </xsl:when> <xsl:when test="./type = 'polygon'"> <xsl:call-template name="createPolygon"/> </xsl:when> </xsl:choose> </xsl:for-each> </xsl:template> <xsl:template name="createRectangle"> <xsl:variable name="x" select="./x"/> <xsl:variable name="y" select="./y"/> <xsl:variable name="width" select="./width"/> <xsl:variable name="height" select="./height"/> <xsl:variable name="style" select="./style"/> <rect x="{$x}" y="{$y}" width="{$width}" height="{$height}" style="{$style}"/> </xsl:template> <xsl:template name="createPolygon"> <xsl:variable name="points" select="./points"/> <xsl:variable name="style" select="./style"/> <polygon points="{$points}" style="{$style}"/> </xsl:template> </xsl:stylesheet>
Listing 17.14 starts by matching the root element ('/'), generating the outermost SVG element, and then invoking the main loop of the XSL stylesheet via the XSL code in bold, as listed below:
<xsl:template match="/"> <svg> <g> <xsl:apply-templates/> </g> </svg> </xsl:template>
The main loop in Listing 17.14 is executed by means of the following type of XSL statement,
<xsl:for-each select="."> <!- add processing logic for each node here -> </xsl:for-each>
and the logic that decides which XSL template to invoke is based on the content of each type element, as shown below:
<xsl:template match="objects/object"> <xsl:for-each select="."> <xsl:choose> <xsl:when test="./type = 'rect'"> <xsl:call-template name="createRectangle"/> </xsl:when> <xsl:when test="./type = 'polygon'"> <xsl:call-template name="createPolygon"/> </xsl:when> </xsl:choose> </xsl:for-each> </xsl:template>
Notice that the <xsl:when> logic in the preceding loop only checks for object elements that contain a type element whose value is either rect or polygon (hence, the ellipse element is ignored). Whenever one of these two matching elements is encountered, an XSL template is explicitly invoked: one template generates an SVG rect element and the other template generates an SVG polygon element.
The createRectangle template for generating an SVG rect element is:
<xsl:template name="createRectangle"> <xsl:variable name="x" select="./x"/> <xsl:variable name="y" select="./y"/> <xsl:variable name="width" select="./width"/> <xsl:variable name="height" select="./height"/> <xsl:variable name="style" select="./style"/> <rect x="{$x}" y="{$y}" width="{$width}" height="{$height}" style="{$style}"/> </xsl:template>
The createRectangle template requires the value of five elements from the XML document: the x-coordinate and y-coordinate of the upper-left corner of the rectangle, the width and height of the rectangle, and the style attribute of the rectangle.
The createPolygon template for generating an SVG polygon element is:
<xsl:template name="createPolygon"> <xsl:variable name="points" select="./points"/> <xsl:variable name="style" select="./style"/> <polygon points="{$points}" style="{$style}"/> </xsl:template>
The createPolygon template is shorter than the createRectangle template because it only requires the points element and the style element from the XML document.
Although Listing 17.14 contains a significant amount of XSL code, it has been organized in a structured fashion to make it easier for you to understand the logic of each component. Incidentally, a good exercise would be to write the corresponding code required for processing an SVG ellipse element. When you are done, add your own SVG-based elements to the XML document-and the corresponding code in the XSL stylesheet. It will help you attain a good comfort level with the XSL code.
|
|