如何使用 jQuery 搜索 JSON 树

我有一个关于在 JSON 中搜索特定信息的问题:

 {
"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? 例如,我希望在 JSON 中搜索一个名为 Peter 的人,当我找到一个匹配项时,我希望显示关于该匹配项的附加信息(在本例中是关于名为 Peter 的人) ,例如一个人的年龄。

255190 次浏览

一旦将 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 !
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

有一些 js-library 可以帮助你:

您可能还想看看 躺椅,它是一个 JSON-Document-Store,在浏览器中工作,具有各种查询机制。

我发现 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
}
});
    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;






}

您可以使用 Jsel-https://github.com/dragonworx/jsel(为了完全公开,我是这个库的所有者)。

它使用了一个真正的 XPath 引擎,并且是高度可定制的,可以在 Node.js 和浏览器中运行。

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

如果您总是使用相同的 JSON 模式,那么您可以使用 jsel 创建自己的模式,并且能够使用更短的表达式,如:

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

可以使用 DefiantJS (http://defiantjs.com)通过“ search”方法扩展全局对象 JSON。可以使用它在 JSON 结构上查询 XPath 查询。例如:

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/

我有类似的条件,加上我的 Search Query 不限于特定的 Object 属性(像“ John”Search Query 应该与 first _ name 和 last _ name 属性匹配)。在花了几个小时之后,我从 Google 的 角度项目中得到了这个函数。他们处理了所有可能的案子。

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

您可以像下面这样使用 $. grep ()搜索 json 对象数组:

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

您不必使用 jQuery。普通的 JavaScript 就可以了。我不推荐任何将 XML 标准移植到 JavaScript 上的库,而且没有其他解决方案可以解决这个问题,所以我编写了自己的库。

我将正则表达式改编为使用 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

对于 JSON 字符串,其工作原理完全相同(除非您显式地搜索逗号和花括号,在这种情况下,我建议在执行 regex 之前对 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/上编写的库和代码