xslt parsing: Inkscape uses comma as decimal separator, whereas xsltproc does not
Steps to reproduce:
- Save svg2xaml.xsl in the extensions directory. It's a modified file with some XAML bugfixes, which exposes the bug
- open Inkscape
- export the following file to XAML: xslt_test.svg
- run xsltproc on the file:
xsltproc svg2xaml.xsl xslt_test.svg > xsltproc_output.xaml
What happened?
The XSLT processing sheet contains the following template for processing radial gradients:
<xsl:if test="@cx and @cy">
<xsl:attribute name="Center">
<xsl:choose>
<xsl:when test="contains(@cx, '%') and contains(@cy, '%')">
<xsl:value-of select="concat(translate(number(substring-before(@cx, '%')) div 100, ',', '.'), ',', translate(number(substring-before(@cy, '%')) div 100, ',', '.'))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(@cx - $left, ',', @cy - $top)" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
The SVG file contains
<radialGradient
gradientUnits="userSpaceOnUse"
r="11.154825"
fy="299.30283"
fx="306.00046"
cy="299.30283"
cx="306.00046"
id="radialGradient4130"
xlink:href="#linearGradient4124"
inkscape:collect="always" />
so we'll use the second part of the template (<xsl:otherwise>
)
The file processed with Inkscape contains
<RadialGradientBrush xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Key="radialGradient4130"
MappingMode="Absolute" Center="306,00046,299,30283" GradientOrigin="306,00046,299,30283" RadiusX="11.154825" RadiusY="11.154825">
And the file processed with XSLTproc contains
<RadialGradientBrush xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Key="radialGradient4130"
MappingMode="Absolute" Center="306.00046,299.30283" GradientOrigin="306.00046,299.30283" RadiusX="11.154825" RadiusY="11.154825">
The dots in the XSLTproc file are commas in the Inkscape file, which leads to an XAML syntax error.
What should have happened?
Inkscape should yield the same result as xsltproc. After all, Inkscape calls libxslt, which is the library behind xsltproc.
In the current svg2xaml version checked into the extensions repo, the problem is avoided by using
<xsl:value-of select="concat(round(@cx - $left), ',', round(@cy - $top))" />
which introduces rounding errors. The problem can be fixed inside the XSLT file by using
<xsl:value-of select="concat(translate(@cx - $left, ',', '.'), ',', translate(@cy - $top, ',', '.'))" />
but that's a hackfix.
The MWE from libxslt (http://www.xmlsoft.org/libxslt/tutorial/libxslttutorial.html), which has almost the same calls as https://gitlab.com/inkscape/inkscape/-/blob/master/src/extension/implementation/xslt.cpp, gives the same result as xsltproc, even after
xmlSubstituteEntitiesDefault(1);
xmlLoadExtDtdDefaultValue = 1;
is removed, but they shouldn't contibute to the bug anyway.
Edit: Starting Inkscape with LANG=en_US.UTF8 ./inkscape.exe
makes the bug disappear.
Inkscape Version and Operating System:
- Inkscape Version: 1.1-dev (6b4d57f, 2020-04-01)
- Operating System: Windows 10
- Operating System version: 10.0.18362