使用XQuery计算字符串中出现的单词数

时间:2013-02-27 21:20:27

标签: xquery

我们有一个非常相似的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<nodeOne>
  <nodeTwo>
    <nodeThree>
      foo bar zoo
    </nodeThree>
  </nodeTwo>
</nodeOne>
<nodeOne>
  <nodeTwo>
    <nodeThree>
      foo bar
    </nodeThree>      
  </nodeTwo>
</nodeOne>
<nodeOne>
  <nodeTwo>
    <nodeThree>
      zoo bar
    </nodeThree>      
  </nodeTwo>
</nodeOne>

我想要实现的是计算nodeThree内每个单词(由空格分隔)的出现次数。考虑到上面的例子,输出将是:

foo 2
bar 3
zoo 2

我尝试获取text()的每个nodeThree,并尝试将tokenize()转换为字符串序列。然后,我想,我可能能够加入他们和团队,然后计算,但我无法这样做。到目前为止已经尝试了很多东西。

1 个答案:

答案 0 :(得分:2)

首先请注意,除非您创建一个根节点来包装它,否则您的XML格式不正确(即它不是真正的XML)。

如果考虑性能,这个问题更适合利用带有频率数据的单词索引,就像在XML数据库中一样。在纯XQuery中解决这个问题对于大型XML来说可能要慢得多,但解决了这个问题:

let $xml :=
    <root>
    <nodeOne>
      <nodeTwo>
        <nodeThree>
          foo bar zoo
        </nodeThree>
      </nodeTwo>
    </nodeOne>
    <nodeOne>
      <nodeTwo>
        <nodeThree>
          foo bar
        </nodeThree>      
      </nodeTwo>
    </nodeOne>
    <nodeOne>
      <nodeTwo>
        <nodeThree>
          zoo bar
        </nodeThree>      
      </nodeTwo>
    </nodeOne>
    </root>
let $toks := $xml//text()/fn:tokenize(fn:normalize-space(.),'\s')
for $t in distinct-values($toks)
let $count := count($toks[. = $t])
return element { $t } {
    attribute count { $count }
} 
=>
<foo count="2"/>
<bar count="3"/>
<zoo count="2"/>