跳转到内容

XQuery/过滤单词

来自维基教科书,开放的书籍,开放的世界

有时您有一个文本主体,并且您想过滤掉给定列表中的单词,通常称为停用词列表

屏幕图像

[编辑 | 编辑源代码]
屏幕图像

示例程序

[编辑 | 编辑源代码]
xquery version "1.0";

(: Test to see if a word is in a list :)

declare namespace exist = "http://exist.sourceforge.net/NS/exist";
declare option exist:serialize "method=xhtml media-type=text/html indent=yes omit-xml-declaration=yes";

(: A list of words :)
let $stopwords :=
<words>
   <word>a</word>
   <word>and</word>
   <word>in</word>
   <word>the</word>
   <word>or</word>
   <word>over</word>
</words>

let $input-text := 'a quick brown fox jumps over the lazy dog'
return
<html>
   <head>
      <title>Test of is a word on a list</title>
     </head>
   <body>
   <h1> Test of is a word on a list</h1>

   <h2>WordList</h2>
   <table border="1">
     <thead>
       <tr>
         <th>StopWord</th>
       </tr>
     </thead>
     <tbody>{
     for $word in $stopwords/word
     return
        <tr>
           <td align="center">{$word}</td>
        </tr>
     }</tbody>
   </table>

   <h2>Sample Input Text</h2>
   <p>Input Text: <div style="border:1px solid black">{$input-text}</div></p>
   <table border="1">
     <thead>
       <tr>
         <th>Word</th>
         <th>On List</th>
       </tr>
     </thead>
     <tbody>{
     for $word in tokenize($input-text, '\s+')
     return
     <tr>
        <td>{$word}</td>
        <td>{
          if ($stopwords/word = $word)
            then(<span style="color:green;">true</span>)
            else(<span style="color:red;">false</span>)
        }</td>
     </tr>
     }</tbody>
   </table>
  </body>
</html>

输入字符串使用tokenize函数拆分为单词,该函数接受两个参数,要解析的字符串和用正则表达式表示的分隔符。这里的单词由一个或多个空格分隔。结果是一个单词序列。

该程序使用 XPath 泛化相等来比较序列$stopwords/word和序列(一个项目)$word。如果这两个序列具有公共项目,即停用词列表包含该词,则为真。

替代编码

[编辑 | 编辑源代码]

您还可以使用量化表达式来使用some...satisfies执行停用词查找——参见XQuery/量化表达式表达式,例如

   some $word in $stopwords
   satisfies ($word = $thisword)

还有其他选择;停用词作为字符串序列,或者是一个长字符串,并使用 contains() 或数据库中的元素。

但是,性能存在显著差异。有一组测试显示了多种选择之间的差异。单元测试

这些测试表明,在 eXist db 平台上,建议的实现都远非最佳。与元素相比,针对字符串序列的测试大约需要五分之一的时间。泛化相等性与使用限定表达式的优越性相同。

[编辑 | 编辑源代码]

看起来首选的方法是

let $stopwords := ("a","and","in","the","or","over")
let $input-string :=  'a quick brown fox jumps over the lazy dog'
let $input-words := tokenize($input-string, '\s+')
return
    for $word in $input-words
    return $stopwords = $word

如果停用词作为元素保存,最好先转换为原子序列

let $stopwords :=
<words>
   <word>a</word>
   <word>and</word>
   <word>in</word>
   <word>the</word>
   <word>or</word>
   <word>over</word>
</words>
let $stopwordsx := $stopwords/word/string(.)
let $input-string :=  'a quick brown fox jumps over the lazy dog'
let $input-words := tokenize($input-string, '\s+')
return
    for $word in $input-words
    return $stopwordsx = $word

请注意,在数据库中引用停用词列表略微提高了性能。

华夏公益教科书