Сравните строку с несколькими значениями свойств JSON, используя JSONPath - PullRequest
0 голосов
/ 11 августа 2011

Я создаю элемент управления для текстового поля с предложением поиска в 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}, но если бы я напечатал Джима вместо Джеймса, он бы ничего не возвратил, если бы я не выполнил два отдельных запроса JSONPath - один для имени, а другой для электронного письма.

То, что я ищу, - это элегантный способ сделать оператор OR с JSONPath, чтобы я мог протестировать одну строку для нескольких значений свойств JSON.

Вот псевдо-код (нерабочий) , который описывает то, что я ищу:

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

Кто-нибудь знает способ сделать это?

Ответы [ 3 ]

0 голосов
/ 14 января 2014

Лучшим способом является использование DefiantJS (http://defiantjs.com).). Эта библиотека расширяет глобальный объект JSON методом «поиск», с помощью которого можно запрашивать структуру JSON с помощью выражений XPath. Этот метод возвращает совпадения в массиве.(пусто, если совпадений не найдено).

Вот рабочий код 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 [содержит (., "Jim")]' найдет все поля в GMAIL независимо от имени поля.Чтобы явно ограничить поиск полями «имя» и «электронная почта», запрос должен выглядеть следующим образом:

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

Чтобы получить представление о том, насколько мощен XPath, ознакомьтесь с этим инструментом XPath Evaluator;http://www.defiantjs.com/#xpath_evaluator

0 голосов
/ 20 августа 2015

Если вы используете парсер Гесснера, вы можете использовать оператор || в своем выражении следующим образом:

var search_path = '$.*[?(/jim/i.test(@.name) || /jim/i.test(@.email))]';
0 голосов
/ 02 сентября 2011

Я бы создал более простую структуру данных, которая сопоставляет условия поиска с именем контакта. Получив имя контакта, найдите всю запись, используя jsonPath

...