I want to match results from several partial terms search in a XQuery function
With contains(), only "john do" or "joh" would match results.
$item[contains(., "john do")]
I'd like to do so...
$item[contains(., "joh") and contains(., "do")]
...no matter how many terms are in the search string.
I'm trying to use tokenize(), then a loop on it to create what I want
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
The result of that loop is exactly as I expected it to be, but it has no effect on the XPATH query, as it were just text (and obviously concat() produce just text)
$item[$query]
Did I miss something ? Is any function better than concat() for that example ?
Thanks for any help !
Your approach is simply not a good idea. You could do it that way, but I would strongly recommend you don't. What you are trying to do is construct a XPath/XQuery expression to evaluate it, i.e. you create your code. This is usually not a good idea.
Instead, you can check the condition in a for loop instead of creating this query. Even better, XQuery and XPath (but only XPath 2.0) have quantified expression, which fit perfectly for your use case:
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
This is hopefully easy to grasp, because it is very close to natural language: Every term has to satisfy a certain condition (in your case a contains()
)