I have a stylesheet that processes stylesheets
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="xsl:value-of">
<xsl:copy>
<xsl:copy-of select="@*[name() != 'select']"/>
<xsl:if test="@select">
<xsl:attribute name="select">
<xsl:text>concat('[', "</xsl:text>
<xsl:value-of select="@select" />
<xsl:text>", ']')</xsl:text>
</xsl:attribute>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
and need to to be able to accept any arbitrary combination/sequence of quotes in the select attribute and still produce a correct result.
As a, trivial, example
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:template match="/">
<xsl:value-of select="concat('Style', "sheet")"/>
</xsl:template>
</xsl:stylesheet>
is not processed correctly.
There are numerous questions about specific cases:
- Escape single quote in xslt concat function,
- how to escape single quote in xslt substring function,
- XSLT 1.0 can’t translate apostrophe
but these do not address the general problem. I realise that a recursive function that parsed all the offending characters and replaced them with variable references to constant values could be used, but this would require wrapping the entire string in a concat()
function that would make the resulting code even more unreadable.
While the XSL 2.0 replace()
function and doubling up would solve this quite straightforwardly, there does not appear to be a 1.0 solution for this.
Current output is
<xsl:stylesheet version="1.0" exclude-result-prefixes="msxsl"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:template match="/">
<xsl:value-of select="concat('[', "concat('Style', "sheet")", ']')" />
</xsl:template>
</xsl:stylesheet>
but will not validate as shown.