开发者

Compare a string with multiple JSON property values using JSONPath

I'm building a search suggestion text box control in JavaScript and am trying to find a way to compare the string the user typed against a JSON Object that represents the us开发者_如何学Cer's contact list.

The JSON Object looks like this:

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

Using JSONPath, I've been able to successfully compare the string the user typed against a single field in the contact object (ie. I can test the name, or the email) using the following:

var input = "james";

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

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

Which returns the {James Simpson} contact object, but if I had typed Jim instead of James it would return nothing unless I did two separate JSONPath queries - one against the name and the other against the email.

What I'm looking is an elegant way to do an OR operator with JSONPath so I can test a single string against multiple JSON property values.

Here's the psuedo-code (non-working) that describes what I'm looking for:

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

Does anyone know of a way to do this?


I would create a simpler data structure that maps search terms to a contact name. Once you have a contact name, look up the entire record using jsonPath


A better way is to use DefiantJS (http://defiantjs.com). This lib extends the global object JSON with the method "search" - with which you can query JSON structure with XPath expressions. This method returns the matches in an array (empty if no matches were found).

Here is a working JSfiddle of the code below;
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

The expression '//gmail[contains(., "jim")]' will find all fields under GMAIL regardless of field name. To explicitly constrict the search to the fields "name" and "email", then the query should look like this:

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

To get an idea of how powerful XPath is, check out this XPath Evaluator tool;
http://www.defiantjs.com/#xpath_evaluator


If you are using Goessner's parser, you can use the || operator in your expression as follows:

var search_path = '$.*[?(/jim/i.test(@.name) || /jim/i.test(@.email))]';
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜