2017-05-04 65 views
2

我想匹配來自幾個部分條款導致XQuery函數搜索多含有()基於標記化字符串

  • 「JOH做」匹配「李四」
  • 「做喬」也匹配「李四」

隨着包含(),只有‘約翰做’或‘[約’將匹配結果。

$item[contains(., "john do")] 

我想這樣做......

$item[contains(., "joh") and contains(., "do")] 

...不管有多少項在搜索字符串。

我試圖用記號化(),然後在其上一個循環來創造什麼我想

let $search := "john do" 
let $terms := fn:tokenize($search, '\s') 
let $query := string-join(
    (for $t in $terms 
    return 
     concat('contains(.,"', $t, '")') 
    ), ' and ' 
) 
return $query 

這個循環的結果是完全按照我希望它是,但它沒有任何效果在XPath查詢,因爲它只是文本(顯然CONCAT()生產只是文本)

$item[$query] 

我錯過了什麼?那個例子中的函數比concat()更好嗎?

感謝您的幫助!

回答

1

你的方法根本不是一個好主意。你可以這樣做,但我強烈建議你不要。你要做的是構建一個XPath/XQuery表達式來評估它,即你創建你的代碼。這通常不是一個好主意。

相反,您可以在for循環中檢查條件,而不是創建此查詢。更妙的是,XQuery和XPath(但只有XPath 2.0中)有量化表達,這完全適合您的使用情況:

for $item in $items 
let $search := "john do" 
let $terms := fn:tokenize($item, '\s') 
where every $term in $terms satisfies contains($search, $term) 
return $item 

這是希望容易掌握,因爲它是非常接近自然語言:每短期必須滿足一定的條件(在你的情況下,一個)

+0

非常感謝!我不知道這些表達式,並且它完美地工作。它也很快。我剛剛修改了代碼以標記化$ search而不是$ item,並將contains()設置爲$ item,而不是$ search '爲$ item中的$ item let $ search:=「john do」 let $ terms: = fn:tokenize($ search,'\ s') 其中$ terms中每個$ term滿足包含($ item,$ term) return $ item' –

+0

@GP是的,這聽起來像是更常見的用例和什麼我會預料到的。但是你對我的問題描述就像你想要的那樣。無論如何,這是重要的概念,交換變量很容易:)很高興它有幫助 – dirkk