2013-05-21 80 views
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次國王)

回答

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的,不幸的是它不是全文規範的一部分。
+0

drikk-你是正確的WRT BaseX – John

+0

drikk-但是,我認爲'where'條款應該來了'訂單之前by' – John

+0

你是對的。有趣的是,它也可以在''where''之前的'by by'執行BaseX。 – dirkk

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。根據您的應用程序,您可能需要使用另一個正則表達式進行標記。

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)') 
+0

計數許多「國王」(每個文件太多)。此外,舉例來說,「絕對不等於」王「這個詞的」王者化「。 –