以下是XML文件示例。
<Docs>
<Doc>
<Name>Doc 1</Name>
<Info>Hurray</Info>
</Doc>
<Doc>
<Name>Doc 2</Name>
<Info>Brinjal is king of vegetables.</Info>
</Doc>
<Doc>
<Name>Doc 3</Name>
<Info>Alexandar was a great king. His desire was to conquer the world and rule the world as a king.</Info>
</Doc>
<Doc>
<Name>Doc 4</Name>
<Info>I love cherries.</Info>
</Doc>
<Doc>
<Name>Doc 5</Name>
<Info>Mango is king of fruits. Alphonso is king of mangoes. So Alphonso is king's king.</Info>
</Doc>
</Docs>
我想在标签中搜索单词“king”并返回as输出。我知道这很简单...... :)
但是顺序应该是搜索到的单词的顺序(这里它将是王),即大多数数字将首先出现。
Doc 5(3次王) Doc 3(2次国王) Doc 2(1次王)
答案 0 :(得分:1)
正如您之前在BaseX邮件列表中提出的问题,我假设您使用的是BaseX作为处理器。假设$doc
保存提供的xml输入,以下显示了所需的结果:
for $e in $doc//Doc
let $copy := copy $c := $e/Info modify () return $c
let $count := ft:count($copy[. contains text 'King'])
order by $count descending
where $count > 0
return <Result>{$e/Name}<count>{$count}</count></Result>
这里有两件特别的事情:
$copy
语句是一个简单的副本,是必需的,因为ft:count
期望数据库节点作为输入。如果您的片段已经在数据库中,则不需要此。ft:count
是特定于供应商的BaseX,不幸的是它不是全文规范的一部分。答案 1 :(得分:1)
使用order by
。
let $token := 'king'
for $doc in //Doc
let $count := count(tokenize($doc/Info, "[\W]")[lower-case(.) = lower-case($token)])
where $count > 0
order by $count descending
return concat($doc/Name, " (", $count, " time", "s"[$count>1], " ", $token, ")")
此表达式拆分非单词字符\W
。根据您的应用程序,您可能希望使用另一个正则表达式进行标记化。
答案 2 :(得分:0)
获得所需输出的另一个例子是:
for $Doc in doc("file:/C:/Users/vgv/Desktop/Testing/Untitled1.xml")//Doc
let $DocName := $Doc/Name/text()
let $KingCount := count(tokenize($Doc/Info,'king'))
order by $KingCount descending
return
concat($DocName, ' (', $KingCount, ' times king)')