xslt transformation: xsl:choose and xsl:sort reports syntax error, if xml:space="preserve" is set previously
Hallo,
I've got an Issue with XSL Transformation which fails with an error in xsl:choose and xsl:sort. The issue is due to whitespaces.
Consider the following example (taken from w3schools: https://www.w3schools.com/xml/xsl_choose.asp ) with the slight modification (added xml:space="preserve")
In fact, on w3schools you can also reproduce the issue, maybe because they are using libxslt
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xhtml">
<xsl:template match="/" xml:space="preserve">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<xsl:choose>
<xsl:when test="price > 10">
<td bgcolor="#ff00ff">
<xsl:value-of select="artist"/></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="artist"/></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
And xml:
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
</catalog>
Reported result:
$ xsltproc test.xslt catalog.xml
runtime error: file test.xslt line 16 element choose
xsl:choose: xsl:when expected first
runtime error: file test.xslt line 16 element choose
xsl:choose: xsl:when expected first
no result for catalog.xml
Expected result: Transformation works:
$ xsltproc test.xslt catalog.xml
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<tr>
<td>Empire Burlesque</td>
<td bgcolor="#ff00ff">
Bob Dylan</td>
</tr>
<tr>
<td>Hide your heart</td>
</tr>
</table>
</body>
</html>
$ xsltproc --version
Using libxml 20913, libxslt 10134 and libexslt 820
xsltproc was compiled against libxml 20913, libxslt 10134 and libexslt 820
libxslt 10134 was compiled against libxml 20913
libexslt 820 was compiled against libxml 20913
The 'workaround' is to eiither remove 'xml:space="preserve"' or to literally remove spaces between corresponding tags:
<xsl:choose><xsl:when test="price > 10">
I've looked into the code quickly and found the part which is supposed to ignore whitespeces in the relevant xslt-Nodes, but apparently it doesn't https://gitlab.gnome.org/GNOME/libxslt/-/blob/master/libxslt/xslt.c#L3200