2014-10-20 5 views
2

Я тоже, глядя на тип ключевого слова механизма подсчета, как была размещена здесь Word Frequency Counter in XSLT:Ключевые слова в XSLT

Мой морщин является то, что мои ключевые слова могут иметь несколько слов, например:

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

I играл с кодом из выше вопрос, а что-то вроде этого:

<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 +» разбивает это на слова, но тогда это не будет соответствовать моим секундомерам, поскольку они есть и могут быть несколькими словами.

Может ли кто-нибудь предложить элегантный способ подсчета слов, когда ключевые слова могут иметь несколько разворотов?

Спасибо за любую помощь в этом!

Russ

+0

Стоп-фразы несовместимы со счетными словами. Вы начнете считать фразы вместо слов? Затем рассмотрим «w1 w2 w3». Вы хотите считать (w1, w2, w3) или (w1 w2, w2 w3) или (w1 w2 w3) или объединение всех этих множеств? – kjhughes

+0

Если вы все еще будете считать слова, а не фразы, но хотите, чтобы ваши фразы остановки не влияли на подсчеты, возможно, это соответствовало бы вашим требованиям, чтобы удалить фразы остановки до выполнения подсчета. – kjhughes

+0

SOrry за то, что вводит в заблуждение. Мои стоп-слова на самом деле являются фразами, которые я хотел рассчитать. Я мог бы думать о способах прокрутки, проверяя каждую фразу, но надеялся, что существует аналогичный элегантный способ подсчета фраз, как этот пример, для отдельных слов. –

ответ

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

Не может быть проще? Например:

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

+0

Мне нравится проще, но [это] (http://xsltransform.net/94hvTyW/2) подсчитывает ' xxx audio codec yyy' как соответствующий «аудиокодек», где он, вероятно, не должен. – kjhughes

+0

@kjhughes Вероятно, нет, но это легко фиксируется с помощью другого символа разделителя (вместо пробела) в исходном соединении строк. –

Смежные вопросы