I have a question about searching the JSON for the specific information. For example, I have this JSON file:
{
"people": {
"person": [
{
"name": "Peter",
"age": 43,
"sex": "male"
}, {
"name": "Zara",
"age": 65,
"sex": "female"
}
]
}
}
My question is, how can find a particular person by name and display that person's age with jQuery? For example, I want to search the JSON for a person called Peter and when I find a match I want to display additional information about that match (about person named Peter in this case) such as person's age for example.
This question is related to
javascript
jquery
json
search
tree
You can use DefiantJS (http://defiantjs.com) which extends the global object JSON with the method "search". With which you can query XPath queries on JSON structures. Example:
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;
Here is a working fiddle;
http://jsfiddle.net/hbi99/NhL7p/
You don't have to use jQuery. Plain JavaScript will do. I wouldn't recommend any library that ports XML standards onto JavaScript, and I was frustrated that no other solution existed for this so I wrote my own library.
I adapted regex to work with JSON.
First, stringify the JSON object. Then, you need to store the starts and lengths of the matched substrings. For example:
"matched".search("ch") // yields 3
For a JSON string, this works exactly the same (unless you are searching explicitly for commas and curly brackets in which case I'd recommend some prior transform of your JSON object before performing regex (i.e. think :, {, }).
Next, you need to reconstruct the JSON object. The algorithm I authored does this by detecting JSON syntax by recursively going backwards from the match index. For instance, the pseudo code might look as follows:
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
With this information, it is possible to use regex to filter a JSON object to return the key, the value, and the parent object chain.
You can see the library and code I authored at http://json.spiritway.co/
I have kind of similar condition plus my Search Query not limited to particular Object property ( like "John" Search query should be matched with first_name and also with last_name property ). After spending some hours I got this function from Google's Angular project. They have taken care of every possible cases.
/* 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;
}
};
Once you have the JSON loaded into a JavaScript object, it's no longer a jQuery problem but is now a JavaScript problem. In JavaScript you could for instance write a search such as:
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 !
You can search on a json object array using $.grep() like this:
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);
You could use Jsel - https://github.com/dragonworx/jsel (for full disclosure, I am the owner of this library).
It uses a real XPath engine and is highly customizable. Runs in both Node.js and the browser.
Given your original question, you'd find the people by name with:
// 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
If you you were always working with the same JSON schema you could create your own schema with jsel, and be able to use shorter expressions like:
dom.select("//person[@name='Peter']")
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;
}
There are some js-libraries that could help you with it:
You might also want to take a look at Lawnchair, which is a JSON-Document-Store which works in the browser and has all sorts of querying-mechanisms.
I found ifaour's example of jQuery.each() to be helpful, but would add that jQuery.each() can be broken (that is, stopped) by returning false at the point where you've found what you're searching for:
$.each(json.people.person, function(i, v) {
if (v.name == "Peter") {
// found it...
alert(v.age);
return false; // stops the loop
}
});
Source: Stackoverflow.com