Javascript 递归解析JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4104321/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Recursively parsing JSON
提问by tjsimmons
I have a large JSON object that I created with Python, and I'm needing to display the information on a webpage now. My problem is the size of it; there are nested arrays and objects within, and it is several layers deep at points. I wrote an extremely inelegant (and buggy) JavaScript function to pull the data out, but this seems like a recursive problem to me, and I unfortunately am not used to thinking like that (yet).
我有一个用 Python 创建的大型 JSON 对象,现在我需要在网页上显示信息。我的问题是它的大小;里面有嵌套的数组和对象,而且它有好几层深。我写了一个非常不优雅(和错误)的 JavaScript 函数来提取数据,但这对我来说似乎是一个递归问题,不幸的是我还不习惯这样思考(还)。
Does anyone know of a good solution to parsingreading such an object? My goal here is to really read this somewhat dynamically, since I'm going to have to do this many more times (and each time the object will be different, but with more or less the same structure). The goal is to take this information and show it meaningfully on a web page.
有谁知道解析读取此类对象的好方法?我的目标是真正动态地阅读这个,因为我将不得不多次这样做(并且每次对象都会不同,但或多或少具有相同的结构)。目标是获取这些信息并在网页上有意义地显示它。
Let me know if I can elaborate further.
让我知道我是否可以进一步详细说明。
Edit: Here's the object. I was away from my computer when I posted this, plus it's rather large. Parts of it that might be sensitive I've pulled out. And I'm using the JSON2 to parse this into something other than a string. It's just the sized and nestiness that's giving me a problem.
编辑:这是对象。当我发布这个时,我不在我的电脑旁,而且它相当大。我已经删除了其中可能敏感的部分。我正在使用 JSON2 将其解析为字符串以外的内容。这只是给我带来问题的大小和嵌套。
{
"Loop300": [
{
"Loop310": [
{
"N1": {
"idCode": "0400",
"idQual": "ZZ",
"name": "REDACTED",
"entIdCode": "SF"
},
"N3": [
{
"address1": "REDACTED",
"address2": "REDACTED"
}
],
"G61": [
{
"contactFunctionCode": "CN",
"commNumber": "REDACTED",
"commNumQualifier": "TE",
"name": "shipping"
}
],
"N4": [
{}
]
}
],
"L11": [],
"S5": {
"stopReasonCode": "LD",
"stopSeqNum": "1"
},
"Loop350": [
{
"LAD": [],
"OID": {
"weight": "161",
"poNum": "ASDF",
"weightCode": "L",
"unitMeasure": "CA",
"refID": "THING",
"quantity": "6"
},
"Loop360": [
{
"Loop365": [],
"L5": {
"lineNum": "1",
"desc": "STUFF"
}
}
]
},
{
"LAD": [],
"OID": {
"weight": "104",
"poNum": "ZXMO",
"weightCode": "L",
"unitMeasure": "CA",
"refID": "STUFF",
"quantity": "6"
},
"Loop360": [
{
"Loop365": [],
"L5": {
"lineNum": "2",
"desc": "STUFF"
}
}
]
},
{
"LAD": [],
"OID": {
"weight": "1833",
"poNum": "ASDF",
"weightCode": "L",
"unitMeasure": "CA",
"refID": "THEBLOB",
"quantity": "40"
},
"Loop360": [
{
"Loop365": [],
"L5": {
"lineNum": "3",
"desc": "STUFF"
}
}
]
},
{
"LAD": [],
"OID": {
"weight": "229",
"poNum": "FDSA",
"weightCode": "L",
"unitMeasure": "CA",
"refID": "BATMAN",
"quantity": "6"
},
"Loop360": [
{
"Loop365": [],
"L5": {
"lineNum": "4",
"desc": "STUFF"
}
}
]
}
],
"AT5": [],
"G62": [
{
"date": "20100817",
"datequalifier": "10"
},
{
"date": "20100817",
"datequalifier": "38"
}
],
"NTE": [
{
"refCode": "OTH",
"desc": "No Touch"
}
]
},
{
"Loop310": [
{
"N1": {
"idCode": "9998000006",
"idQual": "ZZ",
"name": "REDACTED",
"entIdCode": "SF"
},
"N3": [
{
"address1": "REDACTED"
}
],
"G61": [
{
"contactFunctionCode": "CN",
"commNumber": "REDACTED",
"commNumQualifier": "TE",
"name": "REDACTED"
}
],
"N4": [
{}
]
}
],
"L11": [],
"S5": {
"stopReasonCode": "LD",
"stopSeqNum": "2"
},
"Loop350": [
{
"LAD": [],
"OID": {
"poNum": "QWERTY",
"refID": "ASDF",
"unitMeasure": "PL",
"quantity": "1"
},
"Loop360": [
{
"Loop365": [],
"L5": {
"lineNum": "1",
"desc": "PORT"
}
}
]
}
],
"AT5": [],
"G62": [
{
"date": "20100817",
"datequalifier": "10"
},
{
"date": "20100817",
"datequalifier": "38"
}
],
"NTE": [
{
"refCode": "OTH",
"desc": "Driver Count Required"
}
]
},
{
"Loop310": [
{
"N1": {
"idCode": "9998000070",
"idQual": "ZZ",
"name": "PLACE",
"entIdCode": "ST"
},
"N3": [
{
"address1": "PLACE"
}
],
"G61": [
{
"contactFunctionCode": "CN",
"commNumber": "XXXXXXXXXX",
"commNumQualifier": "TE",
"name": "X"
}
],
"N4": [
{}
]
}
],
"L11": [],
"S5": {
"stopReasonCode": "UL",
"stopSeqNum": "3"
},
"Loop350": [
{
"LAD": [],
"OID": {
"poNum": "JOE",
"refID": "SUPERMAN",
"unitMeasure": "PL",
"quantity": "1"
},
"Loop360": [
{
"Loop365": [],
"L5": {
"lineNum": "1",
"desc": "PORT"
}
}
]
}
],
"AT5": [],
"G62": [
{
"date": "20100817",
"datequalifier": "68"
},
{
"date": "20100817",
"datequalifier": "54"
}
],
"NTE": [
{
"refCode": "OTH",
"desc": "No Touch"
}
]
},
{
"Loop310": [
{
"N1": {
"idCode": "0000403803",
"idQual": "ZZ",
"name": "REDACTED",
"entIdCode": "ST"
},
"N3": [
{
"address1": "REDACTED"
}
],
"G61": [
{
"contactFunctionCode": "CN",
"commNumber": "0000000000",
"commNumQualifier": "TE",
"name": "REDACTED"
}
],
"N4": [
{}
]
}
],
"L11": [
{
"qualifier": "DO",
"refID": "THETHING"
}
],
"S5": {
"stopReasonCode": "UL",
"stopSeqNum": "4"
},
"Loop350": [
{
"LAD": [],
"OID": {
"weight": "161",
"poNum": "UIP",
"weightCode": "L",
"unitMeasure": "CA",
"refID": "Hyman",
"quantity": "6"
},
"Loop360": [
{
"Loop365": [],
"L5": {
"lineNum": "1",
"desc": "STUFF"
}
}
]
},
{
"LAD": [],
"OID": {
"weight": "104",
"poNum": "JKLM",
"weightCode": "L",
"unitMeasure": "CA",
"refID": "SUSAN",
"quantity": "6"
},
"Loop360": [
{
"Loop365": [],
"L5": {
"lineNum": "2",
"desc": "STUFF"
}
}
]
},
{
"LAD": [],
"OID": {
"weight": "1833",
"poNum": "ASDF",
"weightCode": "L",
"unitMeasure": "CA",
"refID": "JOE",
"quantity": "40"
},
"Loop360": [
{
"Loop365": [],
"L5": {
"lineNum": "3",
"desc": "STUFF"
}
}
]
},
{
"LAD": [],
"OID": {
"weight": "229",
"poNum": "AAAA",
"weightCode": "L",
"unitMeasure": "CA",
"refID": "ASDF",
"quantity": "6"
},
"Loop360": [
{
"Loop365": [],
"L5": {
"lineNum": "4",
"desc": "STUFF"
}
}
]
}
],
"AT5": [],
"G62": [
{
"date": "20100817",
"datequalifier": "68"
},
{
"date": "20100817",
"datequalifier": "54"
}
],
"NTE": [
{
"refCode": "OTH",
"desc": "Driver Assist Required"
}
]
}
],
"SE": {
"numSegments": "70",
"controlNum": "0002"
},
"Loop100BT": [],
"L11": [
{
"qualifier": "VD",
"refID": "SALLY"
},
{
"qualifier": "SI",
"refID": "MARK"
},
{
"qualifier": "CR",
"refID": "JOE"
},
{
"qualifier": "RB",
"refID": "USD"
},
{
"qualifier": "TH",
"refID": "REDACTED"
}
],
"PLD": [],
"L3": {
"weight": "2328",
"advances": "0",
"rateQual": "FR",
"charge": "05",
"freightRate": "",
"weightQual": "G",
"quantity": "59"
},
"B2": {
"ordernum": "12345",
"paymethod": "PP",
"scac": "XXXX"
},
"Loop100VI": [
{
"N1": {
"name": "REDACTED",
"entIdCode": "AA"
},
"G61": [
{
"contactFunctionCode": "CN",
"commNumber": "REDACTED",
"contactReference": "0563",
"commNumQualifier": "TE",
"name": "REDACTED"
},
{
"contactFunctionCode": "IC",
"commNumber": "REDACTED",
"commNumQualifier": "EM",
"name": "REDACTED"
},
{
"contactFunctionCode": "ZZ",
"name": "REDACTED"
}
]
}
],
"G62": [
{
"date": "20100827",
"timequalifier": "1",
"datequalifier": "64",
"time": "1302"
}
],
"Loop100CB": [],
"NTE": [
{
"refCode": "ZZZ",
"desc": "26"
},
{
"refCode": "OTH",
"desc": "No Touch"
},
{
"refCode": "OTH",
"desc": "Driver Count Required"
},
{
"refCode": "OTH",
"desc": "No Touch"
},
{
"refCode": "OTH",
"desc": "Driver Assist Required"
}
],
"B2A": {
"purpose": "00"
},
"N7": [
{
"equipLength": "4800",
"equipHeight": "0",
"weight": "2328",
"equipWidth": "0",
"equipNum": "ZZZZ",
"equipType": "TV",
"weightQual": "G"
}
]
}
Thanks, T.J.
谢谢,TJ
回答by Ian S Williams
do your mean something like this?
你的意思是这样吗?
function iterateAttributesAndFormHTMLLabels(o){
var s = '';
for(var a in o){
if (typeof o[a] == 'object'){
s+='<label><font color=green>'+a+':</font></label><br />';
s+=iterateAttributesAndFormHTMLLabels(o[a]);
}else{
s+='<label>'+a+': <font color=blue>'+o[a]+'</font></label><br />';
}//end if
}//end for
return s;
}//end function
data = {...};
var html = iterateAttributesAndFormHTMLLabels(data);
No idea if it works in all browsers, does in Chrome and firefox
不知道它是否适用于所有浏览器,适用于 Chrome 和 firefox
cheers, Ian
干杯,伊恩
回答by Sky Sanders
I can appreciate that you are trying to make your question more specific but there is simply not enough information.
我可以理解您正在尝试使您的问题更具体,但根本没有足够的信息。
The json presented is extremely abstract, most of the keys infer little or no context to the meaning of the data, the structure is quite expansive making the effort to glean the meaning problematic.
呈现的 json 非常抽象,大多数键很少或没有推断出数据含义的上下文,结构非常广泛,因此努力收集含义有问题。
'Meaningful' is an ambiguous, relative and subjective term.
“有意义”是一个模棱两可的、相对的和主观的术语。
Please try to condense and clarify your data exemplar and be more specific in how you would propose to present it and you will have more luck getting answers and guidance relevant to your requirements.
请尝试浓缩和澄清您的数据示例,并更具体地说明您打算如何呈现它,您将更幸运地获得与您的要求相关的答案和指导。
Cheers
干杯
this is my original answer to the question as originally stated
这是我最初对问题的原始回答
Include https://github.com/douglascrockford/JSON-js/blob/master/json2.jsin your page. If the browser does not have native JSON, it will fill in.
在您的页面中包含https://github.com/douglascrockford/JSON-js/blob/master/json2.js。如果浏览器没有原生 JSON,它会填写。
then
然后
var myobj = JSON.parse(myjsonstring);
rolling your own is just a silly thing to do.
滚动你自己的只是一件愚蠢的事情。
Good luck.
祝你好运。
回答by Lee
I would suggest JQuery's parseJSON()
function.
我建议使用JQuery 的parseJSON()
函数。
JQuery's implementation will use the browser's built-in JSON.parse()
function, if it exists, and if not, it'll fall back to a pure javascript implementation.
JQuery 的实现将使用浏览器的内置JSON.parse()
函数,如果存在,如果不存在,它将回退到纯 javascript 实现。
[edit] as pointed out by @Sky, the jQuery implementation is substantially simpler than the reference implementation provided by json.org, and this could present some issues in cases where the source of your JSON isn't necessarily trusted.
[编辑] 正如@Sky 所指出的,jQuery 实现比json.org提供的参考实现要简单得多,这可能会在 JSON 来源不一定可信的情况下出现一些问题。
My experience is that jQuery's parser willcorrectly consume any valid JSON(if anyone can show otherwise, I would very much like to see it). The problem is that it will alsoconsume a number of things that aren'tJSON--namely, it will consume (and evaluate) any valid javascript expression. Since expressions could contain function calls, this would present a security issue if your JSON comes from an un-trusted source.
我的经验是 jQuery 的解析器会正确地使用任何有效的 JSON(如果有人能以其他方式显示,我非常希望看到它)。问题是它还会消耗一些非JSON的东西——也就是说,它会消耗(并评估)任何有效的 javascript 表达式。由于表达式可能包含函数调用,如果您的 JSON 来自不受信任的来源,这将带来安全问题。
However, if the source of your JSON is trusted (eg. your own server), then I can see no reason to incur the extra overhead (both code size, and performance) of the stricter implementation. This is especiallytrue if you're already including the jQuery core for other reasons (which you may or may not be).
但是,如果您的 JSON 的来源是可信的(例如,您自己的服务器),那么我认为没有理由产生更严格的实现的额外开销(代码大小和性能)。如果您出于其他原因(您可能会或可能不会)已经包含 jQuery 核心,则尤其如此。
Of course, all of this is a fairly pedantic discussion, since both implementations fall back to the browser built-in if it exists -- which it does in all modern browsers. My point is merely that the jQuery implementation has its strengths, and is a perfectly valid choice in many scenarios. In other situations, you may be better served by the reference implementation from json.org.
当然,所有这些都是一个相当迂腐的讨论,因为如果存在的话,两种实现都回退到内置浏览器——它在所有现代浏览器中都是如此。我的观点仅仅是 jQuery 实现有其优势,并且在许多情况下是一个完全有效的选择。在其他情况下,来自json.org的参考实现可能会更好地为您服务。
回答by Mic
You could use a JS templating engine to transform your JSON to a humanly readable HTML.
您可以使用 JS 模板引擎将您的 JSON 转换为人类可读的 HTML。
Here is an example of recursion with the PURE templating lib: http://beebole.com/pure/documentation/recursion-example/
以下是使用 PURE 模板库进行递归的示例:http: //beebole.com/pure/documentation/recursion-example/
The template here is quite generic, using a UL/LI
combination.
这里的模板非常通用,使用了UL/LI
组合。
Or if you want to render it for instance in a textbox you can use JSON.stringify
:
或者,如果您想在文本框中渲染它,您可以使用JSON.stringify
:
document.getElementById('theTextBox').value = JSON.stringify(theJson, null, 2);
The call above to stringify
will indent the JSON with 2 spaces.
上面的调用stringify
将使用 2 个空格缩进 JSON。