【问题标题】:Count the frequency of a word contained in a string in XSLT计算 XSLT 中字符串中包含的单词的频率
【发布时间】:2021-02-17 16:56:08
【问题描述】:

如何计算一个单词在字符串中出现的频率?我必须使用 XSLT 1.0

示例 XML:

<a>
   <b>Can you can a can as a canner can can a can?</b>
</a>

那么“can”这个词在这个字符串中出现了六次?我可以数可以吗? xD

我使用了类似的东西,但只得到“1”

<xsl:value-of select ="count(a/b[contains(.,'can')])" />

附加问题:如何计算“can”和“Can”而不是“canner”?

【问题讨论】:

  • 那么,您使用哪种 XSLT 1 处理器?是否支持 EXSLT 标记化函数以至少拆分该字符串?否则,编写一个命名递归模板,对字符串进行标记并计算您要查找的子字符串。
  • w3.org/1999/XSL/Transform"> 不支持 EXSLT。你能给我一个这个模板的例子吗
  • 如果您无法访问 tokenize 函数,那么您可以编写一个递归模板,该模板将删除空格字符上的字符串并添加遇到您传递的单词的次数。
  • 这取决于你如何定义word。如果——正如你所说——“可以​​吗?”是单词“can”的出现,那么这将是困难的 - 除非你有一个需要忽略的所有可能的标点字符的列表。
  • 你真的需要用 XSLT 1.0 做这个吗?它已经很长了,以后的版本功能更强大。

标签: xml xslt xslt-1.0


【解决方案1】:

以下是您可以作为起点的示例:

XML

<root>
    <string>Can you can a can as a canner can can a can?</string>
</root>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:variable name="upper-case" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lower-case" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="punctuation" select="'.,:;!?'"/>

<xsl:template match="/root">
    <results>
        <xsl:for-each select="string">
            <count>
                <xsl:call-template name="count-word-occurrences">
                    <xsl:with-param name="text" select="translate(translate(., $upper-case, $lower-case), $punctuation, '')"/>
                    <xsl:with-param name="word">can</xsl:with-param>
                </xsl:call-template>
            </count>
        </xsl:for-each>
    </results>
</xsl:template>

<xsl:template name="count-word-occurrences">
    <xsl:param name="text"/>
    <xsl:param name="word"/>
    <xsl:param name="delimiter" select="' '"/>
    <xsl:param name="count" select="0"/>
    
    <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
    <xsl:variable name="new-count" select="$count + ($token = $word)" />
    
    <xsl:choose>
        <xsl:when test="contains($text, $delimiter)">
            <!-- recursive call -->
            <xsl:call-template name="count-word-occurrences">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                <xsl:with-param name="word" select="$word"/>
                <xsl:with-param name="count" select="$new-count"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$new-count"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<results>
  <count>6</count>
</results>

注意事项

  1. 大小写转换仅限于小写ASCII字符;
  2. 标点符号列表不完整;
  3. 请注意标点符号可能代替空格(例如连字符)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    相关资源
    最近更新 更多