2017-05-04 47 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