2013-02-27 3 views
0

У нас есть очень похожий XML файл следующим образом:Подсчет количества вхождений слов в строках с помощью XQuery

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

То, что я хотел бы добиться того, чтобы подсчитать число вхождений каждого слова (delimitered с пробелом) внутри nodeThree. Учитывая приведенный выше пример, результат будет что-то вроде:

foo 2 
bar 3 
zoo 2 

Я попытался принести каждый text() из nodeThree и попытался tokenize() его в последовательность строк. Тогда, подумал я, я мог бы присоединиться к ним и сгруппироваться, посчитать потом, но я не смог этого сделать. Пробовал много вещей до сих пор.

ответ

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"/> 
Смежные вопросы