I am writing a script to find the number of occurrences of a substring in a string in XSLT. It\'s taking too much time when I want to traverse it in more than 200k records.
http://www.xsltfunctions.com/xsl/functx_number-of-matches.html
as documented:
count(tokenize($arg,$pattern)) - 1
I would write it as:
count(tokenize($string,$substring)) - 1
in your case:
count(tokenize('My Name is Rohan and My Home name is also Rohan but one of my firend honey name is also Rohan','Rohan')) - 1
PS: you spelled 'friend' incorrectly.
I tested this method for my own use-case in XSLT version 2.0, It might also work in 1.0 not sure based on the documentation.
I propose:
<xsl:template name="GetNoOfOccurance">
<xsl:param name="String"/>
<xsl:param name="SubString"/>
<xsl:param name="Counter" select="0" />
<xsl:variable name="sa" select="substring-after($String, $SubString)" />
<xsl:choose>
<xsl:when test="$sa != '' or contains($String, $SubString)">
<xsl:call-template name="GetNoOfOccurance">
<xsl:with-param name="String" select="$sa" />
<xsl:with-param name="SubString" select="$SubString" />
<xsl:with-param name="Counter" select="$Counter + 1" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$Counter" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
This XSLT 1.0 solution counts substring occurrences by the use of simple and straightforward recursion. No further template is needed, and the result is the wanted one:
<Root>
<NoofOccurane>3</NoofOccurane>
<NoofOccurane>0</NoofOccurane>
<NoofOccurane>1</NoofOccurane>
</Root>
You can remove your <xsl:template name="replace-string">
and drop in my template. No further code change required, the calling convention is the same.