XSLT 1.0 escaping double quotes and backslash in a string XSLT 1.0 escaping double quotes and backslash in a string json json

XSLT 1.0 escaping double quotes and backslash in a string


Here is an example of how you can combine the two template calls, so that the output from jsonescape is used as an input parameter to escapequote

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">  <xsl:output method="text" />  <xsl:template match="input">    <xsl:call-template name="escapeQuote">      <xsl:with-param name="pText">        <xsl:call-template name="jsonescape">          <xsl:with-param name="str" select="." />        </xsl:call-template>                </xsl:with-param>    </xsl:call-template>  </xsl:template>  <xsl:template name="escapeQuote">      <xsl:param name="pText" select="concat(normalize-space(.), '')" />      <xsl:if test="string-length($pText) >0">          <xsl:value-of select="substring-before(concat($pText, '"'), '"')" />          <xsl:if test="contains($pText, '"')">              <xsl:text>\"</xsl:text>                  <xsl:call-template name="escapeQuote">                  <xsl:with-param name="pText" select="substring-after($pText, '"')" />              </xsl:call-template>          </xsl:if>      </xsl:if>  </xsl:template>  <xsl:template name="jsonescape">   <xsl:param name="str" select="."/>    <xsl:choose>      <xsl:when test="contains($str, '\')">        <xsl:value-of select="concat(substring-before($str, '\'), '\\' )"/>        <xsl:call-template name="jsonescape">          <xsl:with-param name="str" select="substring-after($str, '\')"/>        </xsl:call-template>      </xsl:when>      <xsl:otherwise>          <xsl:value-of select="$str"/>      </xsl:otherwise>    </xsl:choose>  </xsl:template></xsl:stylesheet>

So, given this an input:

<input>Test "out" and \new</input>

The following is output

Test \"out\" and \\new

Note that the order is important, because if you reversed the order of the template calls, the " would get converted to \" by the escapequote template, which would then get converted to \\" by the jsonescape template.

Alternatively, as both template do a similar thing, of putting a \ before specific characters, you could combine the two templates into one.

Try this XSLT too

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">  <xsl:output method="text" />  <xsl:template match="input">    <xsl:call-template name="jsonescape">      <xsl:with-param name="str" select="." />    </xsl:call-template>            </xsl:template>  <xsl:template name="jsonescape">   <xsl:param name="str" select="."/>   <xsl:param name="escapeChars" select="'\"'" />   <xsl:variable name="first" select="substring(translate($str, translate($str, $escapeChars, ''), ''), 1, 1)" />   <xsl:choose>      <xsl:when test="$first">        <xsl:value-of select="concat(substring-before($str, $first), '\', $first)"/>        <xsl:call-template name="jsonescape">          <xsl:with-param name="str" select="substring-after($str, $first)"/>        </xsl:call-template>      </xsl:when>      <xsl:otherwise>          <xsl:value-of select="$str"/>      </xsl:otherwise>    </xsl:choose>  </xsl:template></xsl:stylesheet>