How to search JSON tree with jQuery – Even if we have a good project plan and a logical concept, we will spend the majority of our time correcting errors abaout javascript and jquery. Furthermore, our application can run without obvious errors with JavaScript, we must use various ways to ensure that everything is operating properly. In general, there are two types of errors that you’ll encounter while doing something wrong in code: Syntax Errors and Logic Errors. To make bug fixing easier, every JavaScript error is captured with a full stack trace and the specific line of source code marked. To assist you in resolving the JavaScript error, look at the discuss below to fix problem about How to search JSON tree with jQuery.
Problem :
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.
Solution :
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;
}
});
Based on this answer, you could use something like:
$(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;
}
});
});
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
}
});
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']")
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);
There are some js-libraries that could help you with it:
- JSONPath (something like XPath for JSON-Structures) – http://goessner.net/articles/JsonPath/
- JSONQuery – https://github.com/JasonSmith/jsonquery
- GROQ – https://github.com/sanity-io/GROQ
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.
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/
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;
}
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;
}
};
"matched".search("ch") // yields 3