查找xslt中字符串中子字符串的出现次数 [英] Find the number of occurences of a substring in a string in xslt

查看:136
本文介绍了查找xslt中字符串中子字符串的出现次数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写一个脚本来查找XSLT中字符串中子串的出现次数。当我想在超过20万条记录中遍历它时,需要花费太多时间。任何人都可以帮助我指出一些变化,使它更快,或者其他方式获得发生的数量?

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. Can anyone help me to point out some changes to make it faster, or some other way to get the number of occurrences?

我说的是一个子字符串,而不是一个字符 - 所以我不是在谈论 translate()函数。

I am talking about a substring, not a character - so I'm not talking about the translate() function.

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:template match="/">
    <Root>
      <NoofOccurane>
        <xsl:call-template name="GetNoOfOccurance">
          <xsl:with-param name="String" select="'My Name is Rohan and My Home name is also Rohan but one of my firend honey name is also Rohan'"/>
          <xsl:with-param name="SubString" select="'Rohan'"/>
        </xsl:call-template>
      </NoofOccurane>
      <NoofOccurane>
        <xsl:call-template name="GetNoOfOccurance">
          <xsl:with-param name="String" select="'My Name is Rohan and My Home name is also Rohan but one of my firend honey name is also Rohan'"/>
          <xsl:with-param name="SubString" select="'Sohan'"/>
        </xsl:call-template>
      </NoofOccurane>
      <NoofOccurane>
        <xsl:call-template name="GetNoOfOccurance">
          <xsl:with-param name="String" select="'My Name is Rohan and My Home name is also Mohan but one of my firend honey name is also Rohan'"/>
          <xsl:with-param name="SubString" select="'Mohan'"/>
        </xsl:call-template>
      </NoofOccurane>
    </Root>
  </xsl:template>

  <xsl:template name="GetNoOfOccurance">
    <xsl:param name="String"/>
    <xsl:param name="SubString"/>
    <xsl:variable name ="LenString" select="string-length($String)" />
    <xsl:variable name ="LenSubString" select="string-length($SubString)" />
    <xsl:variable name ="ReplaceString">
      <xsl:call-template name="replace-string">
        <xsl:with-param name="text" select="$String"/>
        <xsl:with-param name="replace" select="$SubString"/>
        <xsl:with-param name="with" select="''"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name ="NewLenString" select="string-length($ReplaceString)" />
    <xsl:variable name ="DiffLens" select ="number($LenString)-number($NewLenString)" />
    <xsl:choose>
      <xsl:when test ="$NewLenString=0 and $LenSubString &gt;0">
        <xsl:value-of select ="1"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select ="number($DiffLens) div number($LenSubString)"/>
      </xsl:otherwise>
    </xsl:choose>    
  </xsl:template>

  <!-- Template to Replace function -->
  <xsl:template name="replace-string">
    <xsl:param name="text"/>
    <xsl:param name="replace"/>
    <xsl:param name="with"/>
    <xsl:choose>
      <xsl:when test="contains($text,$replace)">
        <xsl:value-of select="substring-before($text,$replace)"/>
        <xsl:value-of select="$with"/>
        <xsl:call-template name="replace-string">
          <xsl:with-param name="text" select="substring-after($text,$replace)"/>
          <xsl:with-param name="replace" select="$replace"/>
          <xsl:with-param name="with" select="$with"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

结果是

<Root>
  <NoofOccurane>3</NoofOccurane>
  <NoofOccurane>0</NoofOccurane>
  <NoofOccurane>1</NoofOccurane>
</Root>


推荐答案

我建议:

<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>

这个XSLT 1.0解决方案通过使用简单直接的递归计算子串的出现次数。不需要另外的模板,结果是想要的:

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>

您可以移除< xsl:template name =replace-string > 并放入我的模板。不需要进一步的代码更改,调用约定是一样的。

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.

这篇关于查找xslt中字符串中子字符串的出现次数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆