0

我正在用 JavaScript 构建一个搜索建议文本框控件,并试图找到一种方法来将用户键入的字符串与代表用户联系人列表的 JSON 对象进行比较。

JSON 对象如下所示:

var contacts = {
    'gmail' : [
        { name : 'Joe Smith', email : 'joe.smith@gmail.com' },
        { name : 'James Simpson', email : 'jim.simpson@gmail.com' }
    ]    
}

使用 JSONPath,我已经能够成功地将用户键入的字符串与联系人对象中的单个字段(即我可以测试姓名或电子邮件)进行比较,使用以下方法:

var input = "james";

var search_path = '$.*[?( /' + input + '/i.test(@.name))]';

var results = jsonPath(contacts ,search_path, {resultType:"VALUE"});

它返回{James Simpson}联系人对象,但如果我输入的是 Jim 而不是 James,它将不会返回任何内容,除非我执行了两个单独的 JSONPath 查询——一个针对名称,另一个针对电子邮件。

我正在寻找的是一种使用 JSONPath 执行 OR 运算符的优雅方法,因此我可以针对多个 JSON 属性值测试单个字符串。

这是描述我正在寻找的东西的伪代码(非工作) :

var search_path = '$.*[?( /' + input + '/i.test([ @.name, @.email ]))]';

有谁知道这样做的方法?

4

3 回答 3

0

更好的方法是使用 DefiantJS ( http://defiantjs.com )。这个库使用“search”方法扩展了全局对象 JSON - 您可以使用 XPath 表达式查询 JSON 结构。此方法返回数组中的匹配项(如果未找到匹配项则为空)。

这是下面代码的工作JSfiddle;
http://jsfiddle.net/hbi99/z2Erf/

var data = {
       "gmail": [
          {
             "name": "Joe Smith",
             "email": "joe.smith@gmail.com"
          },
          {
             "name": "James Simpson",
             "email": "jim.simpson@gmail.com"
          }
       ]
    },
    res = JSON.search( data, '//gmail[contains(., "jim")]' );

console.log( res[0].name );
// James Simpson

表达式'//gmail[contains(., "jim")]'将查找 GMAIL 下的所有字段,无论字段名称如何。要将搜索显式限制为“名称”和“电子邮件”字段,则查询应如下所示:

'//gmail[contains(name, "jim") or contains(email, "jim")]'

要了解 XPath 的强大功能,请查看这个 XPath Evaluator 工具;
http://www.defiantjs.com/#xpath_evaluator

于 2014-01-14T17:30:29.873 回答
0

我将创建一个更简单的数据结构,将搜索词映射到联系人姓名。获得联系人姓名后,使用jsonPath

于 2011-09-01T23:09:31.167 回答
0

如果您使用 Goessner 的解析器,则可以||在表达式中使用运算符,如下所示:

var search_path = '$.*[?(/jim/i.test(@.name) || /jim/i.test(@.email))]';
于 2015-08-20T08:31:21.537 回答