Tuesday, September 28, 2010

Replace single quote with two quotes in XSLT

I know most of the people will not need it as very rare this requirement comes and because of it we have to waste hours and hours. In net there are plenty of articles, posts says about how to do replace in XSLT. But, most of them has some requirements like the replace() built in method needs XSLT 2.0 version, or some thing something.... But, if you need simple replace method regardless of the version you have, then you are at right place. There are lot of custom functions written on this already. But, no one of them works for the requirement I have. That is replacing the single quote with two quotes in XSLT. 

The main requirement here is, I am more of SharePoint guy, I use infopath forms for collecting data from users and save them to backend[database]. In the process of it, I have comments fields in the form. There are chances that user may enter single quotes['] in their comments. But, while saving them to the database, the single quote ['] giving problems. Everyone knows that this is the basic problem. So, I have to replace single quote with two single quotes so that the problem will go away.

Complete XSLT file for replacing a string with some other string:
<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>Replace Single Quote with two single quotes
<br />
Original string: Praveen's World
<br />
Replaced String: 
<xsl:variable name="sq">'</xsl:variable>
<xsl:variable name="tsq">''</xsl:variable>
<xsl:variable name="orgString">Praveen's World</xsl:variable>
<xsl:variable name="replacedString">
    <xsl:call-template name="replace_single_quote">
      <xsl:with-param name="string" select="$orgString" />
            <xsl:with-param name="find" select="$sq" />
            <xsl:with-param name="replace" select="$tsq" />
    </xsl:call-template>
  </xsl:variable>
<xsl:value-of select="$replacedString"/>
  </body>
  </html>
</xsl:template>
<xsl:template name="replace_single_quote">
    <xsl:param name="string" select="''"/>
    <xsl:param name="find" select="''"/>
    <xsl:param name="replace" select="''"/>
    <xsl:choose>
        <xsl:when test="contains($string,$find)">
            <xsl:value-of select="concat(substring-before($string,$find),$replace)"/>
            <xsl:call-template name="replace_single_quote">
                <xsl:with-param name="string" select="substring-after($string,$find)"/>
                <xsl:with-param name="find" select="$find"/>
                <xsl:with-param name="replace" select="$replace"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$string"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>

For testing purpose, you can use the online XSLT editor from W3schools.
On the right side editor, remove all the code and copy, paste the above XSLT. And now, click on the button "Edit and Click Me >>". You will see the XSLT working.
But, you may confuse by seeing above code that I have given complete document to you. Everyone is not really good at XSLT as it is being used by very less people. So, I will try to describe it clearly for better understanding.

Declaring variables and calling the replace method:
<xsl:variable name="sq">'</xsl:variable>
<xsl:variable name="tsq">''</xsl:variable>
<xsl:variable name="orgString">Praveen's World</xsl:variable>
<xsl:variable name="replacedString">
    <xsl:call-template name="replace_single_quote">
      <xsl:with-param name="string" select="$orgString" />
            <xsl:with-param name="find" select="$sq" />
            <xsl:with-param name="replace" select="$tsq" />
    </xsl:call-template>
  </xsl:variable>
<xsl:value-of select="$replacedString"/>

Here is the simple explanation:
We have declared 4 variables as described below.
  1. sq - single quote - I have assigned single quote to it.
  2. tsq - two single quotes - I have assigned two single quotes to it.
  3. orgString - original string to replace.
  4. replacedString - The final output string.
  5. Finally, after the replace logic called and executed, I am printing the replaced string at last line mentioned above.
  6. If you observe, the variable "replacedString" I have assigned the return value of the template/function named "replace_single_quote". I am calling it with call-template tag and it will call the template and returns some value. 
The template "replace_single_quote" is what the actual function which takes three parameters.
  1. Original string
  2. string to find.
  3. string to replace.
The template returns the replaced string if any found.
Note: You can pass whatever string you want in place of the sq [find] and tsq[replace] variables.

I hope you understood it well and it solved your problem.

1 comment:

  1. Thank you so much for this! I have looked at the solution for this for hours on end. This was exactly what I needed!

    ReplyDelete