Як шукати дерево JSON за допомогою jQuery


75

У мене питання щодо пошуку конкретної інформації в JSON. Наприклад, у мене є цей файл JSON:

 {
    "people": {
        "person": [
            {
                "name": "Peter",
                "age": 43,
                "sex": "male"
            }, {
                "name": "Zara",
                "age": 65,
                "sex": "female"
            }
        ]
    }
}

Моє питання полягає в тому, як можна знайти конкретну людину по імені та відобразити вік цієї людини за допомогою jQuery? Наприклад, я хочу шукати в JSON людину на ім'я Пітер, і коли я знаходжу відповідність, хочу відобразити додаткову інформацію про цей збіг (про особу на ім'я Петро в даному випадку), наприклад, вік людини, наприклад.

Відповіді:


100
var json = {
    "people": {
        "person": [{
            "name": "Peter",
            "age": 43,
            "sex": "male"},
        {
            "name": "Zara",
            "age": 65,
            "sex": "female"}]
    }
};
$.each(json.people.person, function(i, v) {
    if (v.name == "Peter") {
        alert(v.age);
        return;
    }
});

Приклад .

На основі цієї відповіді ви можете використовувати щось на зразок:

$(function() {
    var json = {
        "people": {
            "person": [{
                "name": "Peter",
                "age": 43,
                "sex": "male"},
            {
                "name": "Zara",
                "age": 65,
                "sex": "female"}]
        }
    };
    $.each(json.people.person, function(i, v) {
        if (v.name.search(new RegExp(/peter/i)) != -1) {
            alert(v.age);
            return;
        }
    });
});

Приклад 2


Ваш приклад працює досить добре, але мені було цікаво, чи можу я якось використати щось подібне: [посилання] api.jquery.com/attribute-equals-selector, щоб знайти свій збіг?
Mentalhead

1
Останнє запитання, чи є спосіб використовувати стандартні селектори jQuery: [посилання] api.jquery.com/category/selectors для вибору та пошуку потрібних даних, чи мені потрібно використовувати функцію each ()?
Mentalhead

1
@Mentalhead: Ні, ці методи використовуються для обробки селекторів DOM. Також ви хочете прокрутити свій об'єкт, і правильним способом зробити це за допомогою jQuery є метод jQuery jQuery.each ()
ifaour

2
Я не можу зрозуміти, як можна замінити peterу своєму виразі змінну ?! Мені потрібно вставити рядок з $(this).val(). Будь-які ідеї?
yckart

Дуже просте і легке рішення .. працювало як шарм .. але, безумовно, потрібні відповідні функції пошуку JSON.
UberNeo

20

Я знайшов приклад ifaour jQuery.each () як корисний, але додав би, що jQuery.each () можна зламати (тобто зупинити), повернувши значення false у тому місці, де ви знайшли те, що шукали:

$.each(json.people.person, function(i, v) {
        if (v.name == "Peter") {
            // found it...
            alert(v.age);
            return false; // stops the loop
        }
});

12

Ви можете використовувати Jsel - https://github.com/dragonworx/jsel (для повного розкриття інформації я є власником цієї бібліотеки).

Він використовує справжній движок XPath і є дуже настроюваним. Запускається як у Node.js, так і у браузері.

Враховуючи ваше початкове запитання, ви знайдете людей по імені:

// include or require jsel library (npm or browser)
var dom = jsel({
    "people": {
        "person": [{
            "name": "Peter",
            "age": 43,
            "sex": "male"},
        {
            "name": "Zara",
            "age": 65,
            "sex": "female"}]
    }
});
var person = dom.select("//person/*[@name='Peter']");
person.age === 43; // true

Якщо ви завжди працювали з однією і тією ж схемою JSON, ви могли б створити свою власну схему за допомогою jsel і мати можливість використовувати коротші вирази, такі як:

dom.select("//person[@name='Peter']")

9

Після завантаження JSON в об’єкт JavaScript це вже не проблема jQuery, а тепер проблема JavaScript. У JavaScript ви можете, наприклад, написати такий пошук, як:

var people = myJson["people"];
var persons = people["person"];
for(var i=0; i < persons.length; ++i) {
    var person_i = persons[i];
    if(person_i["name"] == mySearchForName) {
        // found ! do something with 'person_i'.
        break;
    }
}
// not found !

Замість people["person"]і person_i["name"]можна писати people.personі person_i.nameкоротко.
rsp

2
Що ви маєте на увазі it's no longer a jQuery problem but is now a JavaScript problem?!
ifaour

2
Здавалося, його запитання мало притворство (за моїм прочитанням, хоча я міг помилятися), що селектори jQuery можна використовувати для обходу JSON, чого вони, на мою думку, не можуть. Тож я маю на увазі "проблему JavaScript" у тому сенсі, що основна функція jQuery та можливості селектора не застосовуються.
DuckMaestro

9

Ви можете шукати масив об’єктів json за допомогою $ .grep () таким чином:

var persons = {
    "person": [
        {
            "name": "Peter",
            "age": 43,
            "sex": "male"
        }, {
            "name": "Zara",
            "age": 65,
            "sex": "female"
        }
      ]
   }
};
var result = $.grep(persons.person, function(element, index) {
   return (element.name === 'Peter');
});
alert(result[0].age);

8

Ви можете використовувати DefiantJS ( http://defiantjs.com ), який розширює глобальний об'єкт JSON методом "пошук". За допомогою якого ви можете запитувати запити XPath щодо структур JSON. Приклад:

var byId = function(s) {return document.getElementById(s);},
data = {
   "people": {
      "person": [
         {
            "name": "Peter",
            "age": 43,
            "sex": "male"
         },
         {
            "name": "Zara",
            "age": 65,
            "sex": "female"
         }
      ]
   }
},
res = JSON.search( data, '//person[name="Peter"]' );

byId('name').innerHTML = res[0].name;
byId('age').innerHTML = res[0].age;
byId('sex').innerHTML = res[0].sex;

Ось робоча скрипка;
http://jsfiddle.net/hbi99/NhL7p/


8

Є кілька js-бібліотек, які можуть вам у цьому допомогти:

Можливо, ви також захочете поглянути на Lawnchair , який є сховищем документів JSON, який працює у браузері та має всілякі механізми запитів.


Є також Jsel - github.com/dragonworx/jsel - він використовує справжній механізм XPath і дозволяє вам налаштувати вашу схему, щоб ви могли створювати кращі вирази, якщо це необхідно.
Алі

Газонний стілець виглядає цікаво .. будь-які корисні приклади ??
UberNeo

Ви можете використовувати онлайн-інтерактивний інструмент за адресою dragonworx.github.io/jsel, щоб спробувати різні вирази. У спадному меню "Приклади XPath" є кілька прикладів.
Алі

2
    var GDNUtils = {};

GDNUtils.loadJquery = function () {
    var checkjquery = window.jQuery && jQuery.fn && /^1\.[3-9]/.test(jQuery.fn.jquery);
    if (!checkjquery) {

        var theNewScript = document.createElement("script");
        theNewScript.type = "text/javascript";
        theNewScript.src = "http://code.jquery.com/jquery.min.js";

        document.getElementsByTagName("head")[0].appendChild(theNewScript);

        // jQuery MAY OR MAY NOT be loaded at this stage


    }
};



GDNUtils.searchJsonValue = function (jsonData, keytoSearch, valuetoSearch, keytoGet) {
    GDNUtils.loadJquery();
    alert('here' + jsonData.length.toString());
    GDNUtils.loadJquery();

    $.each(jsonData, function (i, v) {

        if (v[keytoSearch] == valuetoSearch) {
            alert(v[keytoGet].toString());

            return;
        }
    });



};




GDNUtils.searchJson = function (jsonData, keytoSearch, valuetoSearch) {
    GDNUtils.loadJquery();
    alert('here' + jsonData.length.toString());
    GDNUtils.loadJquery();
    var row;
    $.each(jsonData, function (i, v) {

        if (v[keytoSearch] == valuetoSearch) {


            row  = v;
        }
    });

    return row;



}

2

У мене є подібний стан, а також мій пошуковий запит, не обмежений певною властивістю об’єкта (наприклад, пошуковий запит "Джон" повинен відповідати першому імені, а також властивості прізвища). Провівши кілька годин, я отримав цю функцію від проекту Google Angular . Вони подбали про всі можливі випадки.

/* Seach in Object */

var comparator = function(obj, text) {
if (obj && text && typeof obj === 'object' && typeof text === 'object') {
    for (var objKey in obj) {
        if (objKey.charAt(0) !== '$' && hasOwnProperty.call(obj, objKey) &&
                comparator(obj[objKey], text[objKey])) {
            return true;
        }
    }
    return false;
}
text = ('' + text).toLowerCase();
return ('' + obj).toLowerCase().indexOf(text) > -1;
};

var search = function(obj, text) {
if (typeof text == 'string' && text.charAt(0) === '!') {
    return !search(obj, text.substr(1));
}
switch (typeof obj) {
    case "boolean":
    case "number":
    case "string":
        return comparator(obj, text);
    case "object":
        switch (typeof text) {
            case "object":
                return comparator(obj, text);
            default:
                for (var objKey in obj) {
                    if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
                        return true;
                    }
                }
                break;
        }
        return false;
    case "array":
        for (var i = 0; i < obj.length; i++) {
            if (search(obj[i], text)) {
                return true;
            }
        }
        return false;
    default:
        return false;
}
};


0

Вам не потрібно використовувати jQuery. Звичайний JavaScript підійде. Я б не рекомендував жодну бібліотеку, яка переносить стандарти XML на JavaScript, і мене розчарувало, що для цього не існує жодного іншого рішення, тому я написав власну бібліотеку.

Я адаптував регулярний вираз для роботи з JSON.

Спочатку розшифруйте об’єкт JSON. Потім вам потрібно зберегти старти та довжини відповідних підрядків. Наприклад:

"matched".search("ch") // yields 3

Для рядка JSON це працює точно так само (якщо ви явно не шукаєте коми і фігурні дужки, і в цьому випадку я б рекомендував попереднє перетворення вашого об'єкта JSON перед виконанням регулярного виразу (тобто подумайте:, {,}).

Далі вам потрібно реконструювати об’єкт JSON. Алгоритм, автором якого я є, робить це шляхом виявлення синтаксису JSON шляхом рекурсивного повернення назад від індексу відповідності. Наприклад, псевдокод може виглядати наступним чином:

find the next key preceding the match index, call this theKey
then find the number of all occurrences of this key preceding theKey, call this theNumber
using the number of occurrences of all keys with same name as theKey up to position of theKey, traverse the object until keys named theKey has been discovered theNumber times
return this object called parentChain

З цією інформацією можна використовувати регулярний вираз для фільтрації об’єкта JSON для повернення ключа, значення та батьківського ланцюжка об’єктів.

Ви можете побачити бібліотеку та код, автором якого я є, на http://json.spiritway.co/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.