web-dev-qa-db-fra.com

Comment rechercher dans un arbre JSON avec jQuery

J'ai une question sur la recherche d'informations spécifiques dans le JSON. Par exemple, j'ai ce fichier JSON:

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

Ma question est la suivante: comment trouver une personne en particulier par son nom et afficher son âge avec jQuery? Par exemple, je souhaite rechercher dans le JSON une personne appelée Peter et lorsque je trouve une correspondance, je souhaite afficher des informations supplémentaires sur cette correspondance (à propos de la personne nommée Peter dans ce cas), telle que l'âge de la personne, par exemple.

68
Mentalhead
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;
    }
});

Exemple .

Basé sur ceci réponse , vous pourriez utiliser quelque chose comme:

$(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;
        }
    });
});

Exemple 2

93
ifaour

J'ai trouvé l'exemple de ifQuery.each () de ifaour utile, mais j'ajouterais que jQuery.each () peut être cassé (c'est-à-dire arrêté) en renvoyant false au point où vous avez trouvé ce que vous recherchez:

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

Vous pouvez utiliser Jsel - https://github.com/dragonworx/jsel (pour une divulgation complète, je suis le propriétaire de cette bibliothèque).

Il utilise un véritable moteur XPath et est hautement personnalisable. S'exécute dans Node.js et le navigateur.

Étant donné votre question initiale, vous trouveriez les personnes par leur nom avec:

// 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

Si vous travailliez toujours avec le même schéma JSON, vous pouvez créer votre propre schéma avec jsel et pouvoir utiliser des expressions plus courtes, telles que:

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

Une fois que le fichier JSON est chargé dans un objet JavaScript, il ne s'agit plus d'un problème jQuery, mais d'un problème JavaScript. En JavaScript, vous pouvez par exemple écrire une recherche telle que:

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 !
9
DuckMaestro

Vous pouvez effectuer une recherche sur un tableau d'objets JSON en utilisant $ .grep () comme ceci:

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);
7
Dexxo

Vous pouvez utiliser DefiantJS ( http://defiantjs.com ) qui étend l'objet global JSON avec la méthode "search". Avec lequel vous pouvez interroger des requêtes XPath sur des structures JSON. Exemple:

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;

Voici un violon qui fonctionne.
http://jsfiddle.net/hbi99/NhL7p/

7
Hakan Bilgin

Certaines bibliothèques js pourraient vous aider:

Vous voudrez peut-être aussi jeter un œil à Lawnchair , qui est un JSON-Document-Store qui fonctionne dans le navigateur et possède toutes sortes de mécanismes d’interrogation.

7
Martin Schuhfuß
    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
cindy

J'ai une sorte de condition similaire, plus ma requête de recherche n'est pas limitée à une propriété d'objet particulière (telle que la requête de recherche "John" doit correspondre à la propriété first_name et également à la propriété last_name). Après avoir passé quelques heures, j'ai obtenu cette fonction du projet Angular de Google. Ils ont pris en charge tous les cas possibles.

/* 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;
}
};
2
Hardik Sondagar

Vous n'êtes pas obligé d'utiliser jQuery. JavaScript simple fera l'affaire. Je ne recommanderais aucune bibliothèque qui intègre les normes XML dans JavaScript, et comme j'étais frustré par l'absence de toute autre solution, j'ai donc écrit ma propre bibliothèque.

J'ai adapté regex pour travailler avec JSON.

Tout d'abord, stringify l'objet JSON. Ensuite, vous devez stocker les débuts et les longueurs des sous-chaînes correspondantes. Par exemple:

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

Pour une chaîne JSON, cela fonctionne exactement de la même manière (à moins que vous ne recherchiez explicitement des virgules et des accolades, auquel cas je recommanderais une transformation préalable de votre objet JSON avant d'effectuer une expression régulière (c'est-à-dire, pensez:, {,}).

Ensuite, vous devez reconstruire l'objet JSON. L'algorithme que j'ai créé fait cela en détectant la syntaxe JSON en remontant récursivement de l'index de correspondance. Par exemple, le pseudo-code pourrait ressembler à ceci:

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

Avec ces informations, il est possible d’utiliser regex pour filtrer un objet JSON afin de renvoyer la clé, la valeur et la chaîne d’objets parent.

Vous pouvez voir la bibliothèque et le code que j'ai créés à l'adresse http://json.spiritway.co/

0
mikewhit
0
Luca Fagioli