0

下面是一个示例 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”并返回作为输出。我知道这很简单...... :)

但是 的顺序应该按照搜索到的单词的顺序(这里它将是国王),即最多的数字将排在第一位。

文档 5(3 次国王) 文档 3(2 次国王) 文档 2(1 次国王)

4

3 回答 3

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 的供应商,不幸的是它不是全文规范的一部分。
于 2013-05-21T13:15:08.923 回答
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。根据您的应用程序,您可能希望使用另一个正则表达式进行标记化。

于 2013-05-21T13:15:15.093 回答
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)')
于 2013-05-21T13:49:58.473 回答