在嵌套的json对象中查找对象 [英] Finding an object deep in a nested json object
问题描述
我在下面的代码段中嵌套了json对象,并希望查找所有出现的"$ schema"并将包含该架构值的整个对象保存到另一个对象中.我尝试使用lodash过滤器,但未成功.有人有任何建议吗?
I have the nested json object in the snippet below and want to find all occurrences of '$schema' and save the whole object that contains that schema value into another object. I tried using lodash filter but, was unsuccessful. Does anyone have any recommendations.
{
"element": "parseResult",
"content": [
{
"element": "category",
"meta": {
"classes": [
"api"
],
"title": "Test"
},
"attributes": {
"meta": [
{
"element": "member",
"meta": {
"classes": [
"user"
]
},
"content": {
"key": {
"element": "string",
"content": "FORMAT"
},
"value": {
"element": "string",
"content": "1A"
}
}
}
]
},
"content": [
{
"element": "category",
"meta": {
"classes": [
"resourceGroup"
],
"title": "Questions"
},
"content": [
{
"element": "resource",
"meta": {
"title": "Questions"
},
"attributes": {
"href": "/questions"
},
"content": [
{
"element": "transition",
"meta": {
"title": "List All Questions"
},
"content": [
{
"element": "httpTransaction",
"content": [
{
"element": "httpRequest",
"attributes": {
"method": "GET"
},
"content": []
},
{
"element": "httpResponse",
"attributes": {
"statusCode": "200",
"headers": {
"element": "httpHeaders",
"content": [
{
"element": "member",
"content": {
"key": {
"element": "string",
"content": "Content-Type"
},
"value": {
"element": "string",
"content": "application/json"
}
}
}
]
}
},
"content": [
{
"element": "dataStructure",
"content": [
{
"element": "Question List"
}
]
},
{
"element": "asset",
"meta": {
"classes": [
"messageBody"
]
},
"attributes": {
"contentType": "application/json"
},
"content": "[\n {\n \"question\": \"Favourite programming language?\",\n \"published_at\": \"2014-11-11T08:40:51.620Z\",\n \"url\": \"/questions/1\",\n \"choices\": [\n {\n \"choice\": \"Javascript\",\n \"url\": \"/questions/1/choices/1\",\n \"votes\": 2048\n }\n ]\n }\n]"
},
{
"element": "asset",
"meta": {
"classes": [
"messageBodySchema"
]
},
"attributes": {
"contentType": "application/schema+json"
},
"content": "{\n \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n \"type\": \"array\"\n}"
}
]
}
]
}
]
}
]
},
{
"element": "resource",
"meta": {
"title": "Question"
},
"attributes": {
"href": "/questions/{id}",
"hrefVariables": {
"element": "hrefVariables",
"content": [
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "id"
},
"value": {
"element": "number",
"content": 1234
}
}
}
]
}
},
"content": [
{
"element": "transition",
"meta": {
"title": "Retrieve Question"
},
"content": [
{
"element": "httpTransaction",
"content": [
{
"element": "httpRequest",
"attributes": {
"method": "GET"
},
"content": []
},
{
"element": "httpResponse",
"attributes": {
"statusCode": "200",
"headers": {
"element": "httpHeaders",
"content": [
{
"element": "member",
"content": {
"key": {
"element": "string",
"content": "Content-Type"
},
"value": {
"element": "string",
"content": "application/json"
}
}
}
]
}
},
"content": [
{
"element": "dataStructure",
"content": [
{
"element": "Question"
}
]
},
{
"element": "asset",
"meta": {
"classes": [
"messageBody"
]
},
"attributes": {
"contentType": "application/json"
},
"content": "{\n \"question\": \"Favourite programming language?\",\n \"published_at\": \"2014-11-11T08:40:51.620Z\",\n \"url\": \"/questions/1\",\n \"choices\": [\n {\n \"choice\": \"Javascript\",\n \"url\": \"/questions/1/choices/1\",\n \"votes\": 2048\n }\n ]\n}"
},
{
"element": "asset",
"meta": {
"classes": [
"messageBodySchema"
]
},
"attributes": {
"contentType": "application/schema+json"
},
"content": "{\n \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n \"type\": \"object\",\n \"properties\": {\n \"question\": {\n \"type\": \"string\"\n },\n \"published_at\": {\n \"type\": \"string\"\n },\n \"url\": {\n \"type\": \"string\"\n },\n \"choices\": {\n \"type\": \"array\"\n }\n },\n \"required\": [\n \"question\",\n \"published_at\",\n \"url\",\n \"choices\"\n ]\n}"
}
]
}
]
}
]
}
]
}
]
},
{
"element": "category",
"meta": {
"classes": [
"dataStructures"
]
},
"content": [
{
"element": "dataStructure",
"content": [
{
"element": "object",
"meta": {
"id": "Question"
},
"content": [
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "question"
},
"value": {
"element": "string",
"content": "Favourite programming language?"
}
}
},
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "published_at"
},
"value": {
"element": "string",
"content": "2014-11-11T08:40:51.620Z"
}
}
},
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "url"
},
"value": {
"element": "string",
"content": "/questions/1"
}
}
},
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "choices"
},
"value": {
"element": "array",
"content": [
{
"element": "Choice"
}
]
}
}
}
]
}
]
},
{
"element": "dataStructure",
"content": [
{
"element": "object",
"meta": {
"id": "Choice"
},
"content": [
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "choice"
},
"value": {
"element": "string",
"content": "Javascript"
}
}
},
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "url"
},
"value": {
"element": "string",
"content": "/questions/1/choices/1"
}
}
},
{
"element": "member",
"attributes": {
"typeAttributes": [
"required"
]
},
"content": {
"key": {
"element": "string",
"content": "votes"
},
"value": {
"element": "number",
"content": 2048
}
}
}
]
}
]
},
{
"element": "dataStructure",
"content": [
{
"element": "array",
"meta": {
"id": "Question List"
},
"content": [
{
"element": "Question"
}
]
}
]
}
]
}
]
}
]
}
我尝试过这种方法.
function getObject(theObject) {
var result = null;
if(theObject instanceof Array) {
for(var i = 0; i < theObject.length; i++) {
result = getObject(theObject[i]);
}
}
else
{
for(var prop in theObject) {
console.log(prop + ': ' + theObject[prop]);
if(prop == '$schema') {
if(theObject[prop] == 'http://json-schema.org/draft-04/schema#') {
return theObject;
}
}
if(theObject[prop] instanceof Object || theObject[prop] instanceof Array)
result = getObject(theObject[prop]);
}
}
return result;
}
var result = getObject(json);
推荐答案
Jacob,
问题出在您的JSON本身中.您的json是键/值对.键可以是字符串(用引号"引起来)以启用具有空格或特殊字符的属性.例如
The problem is in your JSON itself. Your json is a key/value pair. Keys can be strings (surrounded with "quotes") to enable properties that have spaces or special characters. e.g.
var obj = { "my property": "my value" };
var val = obj["my property"] // "my value";
但是,如果您的值是字符串,则它们的值应仅带有引号,否则它将不会被解析为对象-它将保留为字符串表示形式.
However your values should only have quotes around them if they are strings, otherwise it won't get parsed to an object - it will remain in string representation.
var obj = { "foo" : "{ \"bar\" : \"my value\" }" } // notice I had to escape the strings with backslashes \
var val = obj.foo.bar // error because foo is a string with the value "{ "bar" : "my value" }"
在您的json中,content属性的值是一个字符串:
In your json, the value of the content property is a string:
"content": "{\n \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n \"type\": \"array\"\n}"
您还需要使用\来对引号进行转义这一事实也告诉您这一点.如果您希望内容在第一时间被解析,那么它应该看起来像这样:
The fact that you needed to escape your quotes with \ tells you this as well. If you expect the content to be parsed the first time, then it should look something like this:
"content": { "$schema": "http://json-schema.org/draft-04/schema#", "type": "array" }
如果您无法更改此设置,则可以调用 eval()或 JSON.parse()在内容上将字符串解析为对象(如果您的内容来自用户,这可能是不安全的).
If you can't change this, then you can call an eval() or a JSON.parse() on the content to parse the string to an object (this can be unsafe if your content is coming from the users).
因为您无法更改传入的JSON,所以我创建了一个名为deepParseObject的函数.这绝不是防错的,但我认为它会适合您的情况:
Because you cannot change the JSON coming in, I created a function called deepParseObject. It's by no means error-proof, but I think it will work for your situation:
function deepParseObject(theObject) {
for(var prop in theObject) {
if(typeof theObject[prop] === "string" && (theObject[prop].indexOf('{') == 0 || theObject[prop].indexOf('[') == 0)) {
theObject[prop] = JSON.parse(theObject[prop]);
}
if(theObject[prop] instanceof Object || theObject[prop] instanceof Array)
deepParseObject(theObject[prop]);
}
}
它的作用是解析内容属性,如果它们的值是字符串,并以{
或[
开头.之后,您可以调用我的原始getObject函数.这是矮人.
https://plnkr.co/edit/h06wuAxZkxhwCAho3OK6
What it does is parse the content properties if their values are strings and start with a {
or [
. After that you can call my original getObject function. Here is the plunker.
https://plnkr.co/edit/h06wuAxZkxhwCAho3OK6
我在data.js中调用deepParseObject,而我仅使用AngularJS输出结果...并且因为我喜欢Angular:).
I call deepParseObject in the data.js and I'm only using AngularJS to output the results... and because I like Angular :).
这篇关于在嵌套的json对象中查找对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!