I asked about my XSLT issues on the Gnome XSLT mailing list and got this reply, which neatly summarises where I was going wrong… (though the being ‘shouted at’ part tells you a lot about the dysfunctional aspects of a lot of online software development, but I am used to that by now)
The name of the element is a complex object with a
namespace and a local name.
With <svg width=”1000px” height=”800px” version=”1.1″
xmlns=”http://www.w3.org/2000/svg“>, the element’s name is
{http://www.w3.org/2000/svg}svg. With <svg width=”1000px”
height=”800px” version=”1.1″>, the element’s name is {}svg. These are
NOT THE SAME, and XSLT that works to transform one will not transform
the other. You may as well ask why changing <svg> to <gvs> does not work.
There is a neat answer to this, specifying xpath-default-namespace="http://www.w3.org/2000/svg"
in the xsl tag at the start of the stylesheet (I have to lose the non-standard indent attribute too) – giving this:
<?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.w3.org/2000/svg"> <xsl:param name="colour">yellow</xsl:param> <xsl:template match="/"> <xsl:apply-templates select="svg"/> </xsl:template> <xsl:template match="svg"> <xsl:copy> <xsl:for-each select="@*"> <xsl:copy/> </xsl:for-each> <xsl:text> </xsl:text> <xsl:apply-templates select="rect"/> <xsl:apply-templates select="line"/> <xsl:apply-templates select="text"/> <xsl:apply-templates select="circle"/> </xsl:copy> </xsl:template> <xsl:template match="line"> <xsl:copy> <xsl:for-each select="@*"> <xsl:copy/> </xsl:for-each> </xsl:copy> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="rect"> <xsl:copy> <xsl:for-each select="@*"> <xsl:copy/> </xsl:for-each> </xsl:copy> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="text"> <xsl:copy> <xsl:for-each select="@*|node()"> <xsl:copy/> </xsl:for-each> </xsl:copy> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="circle"> <xsl:if test="@stroke=$colour"> <xsl:copy> <xsl:for-each select="@*"> <xsl:copy/> </xsl:for-each> </xsl:copy> <xsl:text> </xsl:text> </xsl:if> </xsl:template> </xsl:stylesheet>
This is only supported in XSLT 2.0, an accepted standard, but more or less orphaned by the big software houses and, in particular, the browser builders. But help is at hand in the form of the Saxonb XSL processor, so a command line like this:
saxonb-xslt -xsl:pickcolour.xsl -s:memmap.svg -o:test.svg colour=green
does the job.
Related articles
- Using XSLT to manipulate an SVG file (cartesianproduct.wordpress.com)
- XSL problem (cartesianproduct.wordpress.com)
- XSL problem solved (sort of) (cartesianproduct.wordpress.com)
- Xml… (nikhatshahin.wordpress.com)
- Integrating Balanced Scorecard for iPad Using XML (bscipad.wordpress.com)