【问题标题】:Key word count in xsltxslt 中的关键字计数
【发布时间】:2014-10-20 16:00:45
【问题描述】:

我也在查看关键字类型的计数机制,例如在此处发布的Word Frequency Counter in XSLT

我的皱纹是我的关键字可能有多个单词,例如:

<xsl:variable name="stopwords" 
select="('audio codec', 'dual audio', 'audio switch' )"/>

我正在使用上述问题的代码,并且有这样的事情:

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

<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">   

<xsl:variable name="stopwords" 
  select="('audio codec', 'dual audio', 'audio switch' )"/>
     <wordcount>
        <xsl:for-each-group group-by="." select="
            for $w in //text()/tokenize(., '\W+')[not(.=$stopwords)] return $w">
            <word word="{current-grouping-key()}" frequency="{count(current-group())}"/>
        </xsl:for-each-group>
     </wordcount>
</xsl:template>

当然,使用 '\W+' 进行标记会将其分解为单词,但这与我的停用词不匹配,因为它们是并且可以是多个单词。

当关键字可能有多个单词时,任何人都可以提出一种优雅的单词计数方法吗?

感谢您在这方面的任何帮助!

罗斯

【问题讨论】:

  • 有停用词组与计数单词不一致。你要开始数短语而不是单词吗?然后考虑“w1 w2 w3” 你想数 (w1, w2, w3) 还是 (w1 w2, w2 w3) 还是 (w1 w2 w3) 还是所有这些集合的并集?
  • 如果您仍然要计算单词而不是短语,但希望停用词组不会影响计数,那么在执行计数之前删除停用词组可能会满足您的要求。
  • 抱歉误导。我的停用词实际上是我想计算实例的短语。我可以想出循环遍历的方法,检查每个短语,但希望有一种类似的优雅方法来计算短语出现的次数,就像这个例子对单个单词所做的那样。
  • kjhughes,您的答案刚刚被删除。你或其他人这样做了吗?
  • 必须修复以处理文本节点内的多个keyphrases。现在恢复了。我希望它有所帮助。

标签: xml xslt xslt-2.0 word-count


【解决方案1】:

鉴于此输入 XML:

<?xml version="1.0" ?>
<a>
  <b>match: audio switch</b>
  <c>no match:</c>
  <d>no match: audiocodec</d>
  <e attr="no match: audio codec"/>
  No match:  Audio switch/dual AUDIO
  Match x2:  audio switch/dual audio/audio switch
  No match: <f>xxx audio</f><g>codec yyy</g>
</a>

此 XSLT:

<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:f="http://example.com/f"
                exclude-result-prefixes="f">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

  <xsl:variable name="keyphrases" 
                select="('audio codec', 'dual audio', 'audio switch' )"/>

  <xsl:template match="/">
    <xsl:variable name="docText" select="string-join(//text(), '|')"/>
    <keyphrases>
      <xsl:for-each select="$keyphrases">
        <keyphrase phrase="{.}" count="{f:substr-count($docText, .)}"/>
      </xsl:for-each>
    </keyphrases>
  </xsl:template>

  <xsl:function name="f:substr-count">
    <xsl:param name="s"/>
    <xsl:param name="substr"/>
    <xsl:value-of select="if ($s and $substr and contains($s, $substr))
                          then f:substr-count(substring-after($s, $substr), $substr)+1
                          else 0"/>
  </xsl:function>

</xsl:stylesheet>

将生成此输出 XML,用于计算您的“停用”词的出现次数(我将其重命名为 keyphrases):

<?xml version="1.0" encoding="UTF-8"?>
<keyphrases>
   <keyphrase phrase="audio codec" count="0"/>
   <keyphrase phrase="dual audio" count="1"/>
   <keyphrase phrase="audio switch" count="3"/>
</keyphrases>

【讨论】:

    【解决方案2】:

    这不是更简单吗?例如:

        <xsl:for-each select="$stopwords">
            <word word="{.}" frequency="{count(tokenize($all-text, .)) - 1}"/>
        </xsl:for-each>
    

    演示:
    http://xsltransform.net/94hvTyW
    http://xsltransform.net/94hvTyW/1

    为了防止误报匹配,例如“双音频”匹配“个人听力图”,您可以使用:

    tokenize($all-text, concat('\W', ., '\W'))
    

    不幸的是,XPath 正则表达式没有用于单词边界的锚点(请参阅:https://stackoverflow.com/a/25464233/3016153),因此在 $all-text 变量前面加上空格可能会更安全。

    【讨论】:

    • 我喜欢更简单的,但 this&lt;f&gt;xxx audio&lt;/f&gt;&lt;g&gt;codec yyy&lt;/g&gt; 视为匹配“音频编解码器”,而它可能不应该。
    • @kjhughes 可能不会,但这很容易通过在初始字符串连接中使用另一个分隔符(而不是空格)来解决。
    猜你喜欢
    • 2021-03-21
    • 2012-06-14
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多