How can I pretty-print JSON using JavaScript?

匿名 (未验证) 提交于 2019-12-03 01:57:01

问题:

How can I display JSON in an easy-to-read (for human readers) format? I'm looking primarily for indentation and whitespace, with perhaps even colors / font-styles / etc.

回答1:

Pretty-printing is implemented natively in JSON.stringify(). The third argument enables pretty printing and sets the spacing to use:

var str = JSON.stringify(obj, null, 2); // spacing level = 2 

If you need syntax highlighting, you might use some regex magic like so:

function syntaxHighlight(json) {     if (typeof json != 'string') {          json = JSON.stringify(json, undefined, 2);     }     json = json.replace(/&/g, '&').replace(//g, '>');     return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {         var cls = 'number';         if (/^"/.test(match)) {             if (/:$/.test(match)) {                 cls = 'key';             } else {                 cls = 'string';             }         } else if (/true|false/.test(match)) {             cls = 'boolean';         } else if (/null/.test(match)) {             cls = 'null';         }         return '' + match + '';     }); } 

See in action here: jsfiddle

Or a full snippet provided below:

function output(inp) {     document.body.appendChild(document.createElement('pre')).innerHTML = inp; }  function syntaxHighlight(json) {     json = json.replace(/&/g, '&').replace(//g, '>');     return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {         var cls = 'number';         if (/^"/.test(match)) {             if (/:$/.test(match)) {                 cls = 'key';             } else {                 cls = 'string';             }         } else if (/true|false/.test(match)) {             cls = 'boolean';         } else if (/null/.test(match)) {             cls = 'null';         }         return '' + match + '';     }); }  var obj = {a:1, 'b':'foo', c:[false,'false',null, 'null', {d:{e:1.3e5,f:'1.3e5'}}]}; var str = JSON.stringify(obj, undefined, 4);  output(str); output(syntaxHighlight(str));
pre {outline: 1px solid #ccc; padding: 5px; margin: 5px; } .string { color: green; } .number { color: darkorange; } .boolean { color: blue; } .null { color: magenta; } .key { color: red; }



回答2:

User Pumbaa80's answer is great if you have an object you want pretty printed. If you're starting from a valid JSON string that you want to pretty printed, you need to convert it to an object first:

var jsonString = '{"some":"json"}'; var jsonPretty = JSON.stringify(JSON.parse(jsonString),null,2);   

This builds a JSON object from the string, and then converts it back to a string using JSON stringify's pretty print.



回答3:

Based on Pumbaa80's answer I have modified the code to use the console.log colours (working on Chrome for sure) and not HTML. Output can be seen inside console. You can edit the _variables inside the function adding some more styling.

function JSONstringify(json) {     if (typeof json != 'string') {         json = JSON.stringify(json, undefined, '\t');     }      var          arr = [],         _string = 'color:green',         _number = 'color:darkorange',         _boolean = 'color:blue',         _null = 'color:magenta',         _key = 'color:red';      json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {         var style = _number;         if (/^"/.test(match)) {             if (/:$/.test(match)) {                 style = _key;             } else {                 style = _string;             }         } else if (/true|false/.test(match)) {             style = _boolean;         } else if (/null/.test(match)) {             style = _null;         }         arr.push(style);         arr.push('');         return '%c' + match + '%c';     });      arr.unshift(json);      console.log.apply(console, arr); } 

Here is a bookmarklet you can use:

javascript:function JSONstringify(json) {if (typeof json != 'string') {json = JSON.stringify(json, undefined, '\t');}var arr = [],_string = 'color:green',_number = 'color:darkorange',_boolean = 'color:blue',_null = 'color:magenta',_key = 'color:red';json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {var style = _number;if (/^"/.test(match)) {if (/:$/.test(match)) {style = _key;} else {style = _string;}} else if (/true|false/.test(match)) {style = _boolean;} else if (/null/.test(match)) {style = _null;}arr.push(style);arr.push('');return '%c' + match + '%c';});arr.unshift(json);console.log.apply(console, arr);};void(0); 

Usage:

var obj = {a:1, 'b':'foo', c:[false,null, {d:{e:1.3e5}}]}; JSONstringify(obj); 

Edit: I just tried to escape the % symbol with this line, after the variables declaration:

json = json.replace(/%/g, '%%'); 

But I find out that Chrome is not supporting % escaping in the console. Strange... Maybe this will work in the future.

Cheers!



回答4:

I use the JSONView Chrome extension (it is as pretty as it gets :):

Edit: added jsonreport.js

I've also released an online stand-alone JSON pretty print viewer, jsonreport.js, that provides a human readable HTML5 report you can use to view any JSON data.

You can read more about the format in New JavaScript HTML5 Report Format.



回答5:

You can use console.dir(), which is a shortcut for console.log(util.inspect()). (The only difference is that it bypasses any custom inspect() function defined on an object.)

It uses syntax-highlighting, smart indentation, removes quotes from keys and just makes the output as pretty as it gets.

const object = JSON.parse(jsonString)  console.dir(object, {depth: null, colors: true}) 

and for the command line:

cat package.json | node -e "process.stdin.pipe(new stream.Writable({write: chunk => console.dir(JSON.parse(chunk), {depth: null, colors: true})}))"



回答6:

Better way.

Prettify JSON Array in Javascript

JSON.stringify(jsonobj,null,'\t') 


回答7:

For debugging purpose I use:

console.debug("%o", data); 


回答8:

var jsonObj = {"streetLabel": "Avenue Anatole France", "city": "Paris 07",  "postalCode": "75007", "countryCode": "FRA",  "countryLabel": "France" };   document.getElementById("result-before").innerHTML = JSON.stringify(jsonObj); 

// in case of displaying in HTML, you should to add a balise < pre>< /pre>

document.getElementById("result-after").innerHTML = "
"+JSON.stringify(jsonObj,undefined, 2) +"
"


回答9:

Unsatisfied with other pretty printers for Ruby, I wrote my own (NeatJSON) and then ported it to JavaScript including a free online formatter. The code is free under MIT license (quite permissive).

Features (all optional):

  • Set a line width and wrap in a way that keeps objects and arrays on the same line when they fit, wrapping one value per line when they don't.
  • Sort object keys if you like.
  • Align object keys (line up the colons).
  • Format floating point numbers to specific number of decimals, without messing up the integers.
  • 'Short' wrapping mode puts opening and closing brackets/braces on the same line as values, providing a format that some prefer.
  • Granular control over spacing for arrays and objects, between brackets, before/after colons and commas.
  • Function is made available to both web browsers and Node.js.

I'll copy the source code here so that this is not just a link to a library, but I encourage you to go to the GitHub project page, as that will be kept up-to-date and the code below will not.

(function(exports){ exports.neatJSON = neatJSON;  function neatJSON(value,opts){   opts = opts || {}   if (!('wrap'          in opts)) opts.wrap = 80;   if (opts.wrap==true) opts.wrap = -1;   if (!('indent'        in opts)) opts.indent = '  ';   if (!('arrayPadding'  in opts)) opts.arrayPadding  = ('padding' in opts) ? opts.padding : 0;   if (!('objectPadding' in opts)) opts.objectPadding = ('padding' in opts) ? opts.padding : 0;   if (!('afterComma'    in opts)) opts.afterComma    = ('aroundComma' in opts) ? opts.aroundComma : 0;   if (!('beforeComma'   in opts)) opts.beforeComma   = ('aroundComma' in opts) ? opts.aroundComma : 0;   if (!('afterColon'    in opts)) opts.afterColon    = ('aroundColon' in opts) ? opts.aroundColon : 0;   if (!('beforeColon'   in opts)) opts.beforeColon   = ('aroundColon' in opts) ? opts.aroundColon : 0;    var apad  = repeat(' ',opts.arrayPadding),       opad  = repeat(' ',opts.objectPadding),       comma = repeat(' ',opts.beforeComma)+','+repeat(' ',opts.afterComma),       colon = repeat(' ',opts.beforeColon)+':'+repeat(' ',opts.afterColon);    return build(value,'');    function build(o,indent){     if (o===null || o===undefined) return indent+'null';     else{       switch(o.constructor){         case Number:           var isFloat = (o === +o && o !== (o|0));           return indent + ((isFloat && ('decimals' in opts)) ? o.toFixed(opts.decimals) : (o+''));          case Array:           var pieces  = o.map(function(v){ return build(v,'') });           var oneLine = indent+'['+apad+pieces.join(comma)+apad+']';           if (opts.wrap===false || oneLine.length<=opts.wrap) return oneLine;           if (opts.short){             var indent2 = indent+' '+apad;             pieces = o.map(function(v){ return build(v,indent2) });             pieces[0] = pieces[0].replace(indent2,indent+'['+apad);             pieces[pieces.length-1] = pieces[pieces.length-1]+apad+']';             return pieces.join(',\n');           }else{             var indent2 = indent+opts.indent;             return indent+'[\n'+o.map(function(v){ return build(v,indent2) }).join(',\n')+'\n'+indent+']';           }          case Object:           var keyvals=[],i=0;           for (var k in o) keyvals[i++] = [JSON.stringify(k), build(o[k],'')];           if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1kv2?1:0 });           keyvals = keyvals.map(function(kv){ return kv.join(colon) }).join(comma);           var oneLine = indent+"{"+opad+keyvals+opad+"}";           if (opts.wrap===false || oneLine.lengthkv2?1:0 });             keyvals[0][0] = keyvals[0][0].replace(indent+' ',indent+'{');             if (opts.aligned){               var longest = 0;               for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;               var padding = repeat(' ',longest);               for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);             }             for (var i=keyvals.length;i--;){               var k=keyvals[i][0], v=keyvals[i][1];               var indent2 = repeat(' ',(k+colon).length);               var oneLine = k+colon+build(v,'');               keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));             }             return keyvals.join(',\n') + opad + '}';           }else{             var keyvals=[],i=0;             for (var k in o) keyvals[i++] = [indent+opts.indent+JSON.stringify(k),o[k]];             if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1kv2?1:0 });             if (opts.aligned){               var longest = 0;               for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;               var padding = repeat(' ',longest);               for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);             }             var indent2 = indent+opts.indent;             for (var i=keyvals.length;i--;){               var k=keyvals[i][0], v=keyvals[i][1];               var oneLine = k+colon+build(v,'');               keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));             }             return indent+'{\n'+keyvals.join(',\n')+'\n'+indent+'}'           }          default:           return indent+JSON.stringify(o);       }     }   }    function repeat(str,times){ // http://stackoverflow.com/a/17800645/405017     var result = '';     while(true){       if (times & 1) result += str;       times >>= 1;       if (times) str += str;       else break;     }     return result;   }   function padRight(pad, str){     return (str + pad).substring(0, pad.length);   } } neatJSON.version = "0.5";  })(typeof exports === 'undefined' ? this : exports); ?-1:kv1>)>?-1:kv1>


回答10:

Thanks a lot @all! Based on the previous answers, here is another variant method providing custom replacement rules as parameter:

 renderJSON : function(json, rr, code, pre){    if (typeof json !== 'string') {       json = JSON.stringify(json, undefined, '\t');    }   var rules = {    def : 'color:black;',        defKey : function(match){              return '' + match + '';           },    types : [        {           name : 'True',           regex : /true/,           type : 'boolean',           style : 'color:lightgreen;'        },         {           name : 'False',           regex : /false/,           type : 'boolean',           style : 'color:lightred;'        },         {           name : 'Unicode',           regex : /"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?/,           type : 'string',           style : 'color:green;'        },         {           name : 'Null',           regex : /null/,           type : 'nil',           style : 'color:magenta;'        },         {           name : 'Number',           regex : /-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/,           type : 'number',           style : 'color:darkorange;'        },         {           name : 'Whitespace',           regex : /\s+/,           type : 'whitespace',           style : function(match){              return ' ';           }        }       ],      keys : [        {            name : 'Testkey',            regex : /("testkey")/,            type : 'key',            style : function(match){              return '

' + match + '

'; } } ], punctuation : { name : 'Punctuation', regex : /([\,\.\}\{\[\]])/, type : 'punctuation', style : function(match){ return '

________

'; } } }; if('undefined' !== typeof jQuery){ rules = $.extend(rules, ('object' === typeof rr) ? rr : {}); }else{ for(var k in rr ){ rules[k] = rr[k]; } } var str = json.replace(/([\,\.\}\{\[\]]|"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { var i = 0, p; if (rules.punctuation.regex.test(match)) { if('string' === typeof rules.punctuation.style){ return '' + match + ''; }else if('function' === typeof rules.punctuation.style){ return rules.punctuation.style(match); } else{ return match; } } if (/^"/.test(match)) { if (/:$/.test(match)) { for(i=0;i' + match + ''; }else if('function' === typeof p.style){ return p.style(match); } else{ return match; } } } return ('function'===typeof rules.defKey) ? rules.defKey(match) : '' + match + ''; } else { return ('function'===typeof rules.def) ? rules.def(match) : '' + match + ''; } } else { for(i=0;i' + match + ''; }else if('function' === typeof p.style){ return p.style(match); } else{ return match; } } } } }); if(true === pre)str = '
' + str + '
'; if(true === code)str = '' + str + ''; return str; }
;i++){>
;i++){>


回答11:

Douglas Crockford's JSON in JavaScript library will pretty print JSON via the stringify method.

You may also find the answers to this older question useful: How can I pretty-print JSON in (unix) shell script?



回答12:

I ran into an issue today with @Pumbaa80's code. I'm trying to apply JSON syntax highlighting to data that I'm rendering in a Mithril view, so I need to create DOM nodes for everything in the JSON.stringify output.

I split the really long regex into its component parts as well.

render_json = (data) ->   # wraps JSON data in span elements so that syntax highlighting may be   # applied. Should be placed in a `whitespace: pre` context   if typeof(data) isnt 'string'     data = JSON.stringify(data, undefined, 2)   unicode =     /"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?/   keyword =     /\b(true|false|null)\b/   whitespace =  /\s+/   punctuation = /[,.}{\[\]]/   number =      /-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/    syntax = '(' + [unicode, keyword, whitespace,             punctuation, number].map((r) -> r.source).join('|') + ')'   parser = new RegExp(syntax, 'g')    nodes = data.match(parser) ? []   select_class = (node) ->     if punctuation.test(node)       return 'punctuation'     if /^\s+$/.test(node)       return 'whitespace'     if /^\"/.test(node)       if /:$/.test(node)         return 'key'       return 'string'      if /true|false/.test(node)       return 'boolean'       if /null/.test(node)        return 'null'      return 'number'   return nodes.map (node) ->     cls = select_class(node)     return Mithril('span', {class: cls}, node) 

Code in context on Github here



回答13:

It works well:

console.table() 

Read more here: https://developer.mozilla.org/pt-BR/docs/Web/API/Console/table



回答14:

If you need this to work in a textarea the accepted solution will not work.

$("#textarea").append(formatJSON(JSON.stringify(jsonobject),true));

function formatJSON(json,textarea) {     var nl;     if(textarea) {         nl = "  ";     } else {         nl = "
"; } var tab = "    "; var ret = ""; var numquotes = 0; var betweenquotes = false; var firstquote = false; for (var i = 0; i < json.length; i++) { var c = json[i]; if(c == '"') { numquotes ++; if((numquotes + 2) % 2 == 1) { betweenquotes = true; } else { betweenquotes = false; } if((numquotes + 3) % 4 == 0) { firstquote = true; } else { firstquote = false; } } if(c == '[' && !betweenquotes) { ret += c; ret += nl; continue; } if(c == '{' && !betweenquotes) { ret += tab; ret += c; ret += nl; continue; } if(c == '"' && firstquote) { ret += tab + tab; ret += c; continue; } else if (c == '"' && !firstquote) { ret += c; continue; } if(c == ',' && !betweenquotes) { ret += c; ret += nl; continue; } if(c == '}' && !betweenquotes) { ret += nl; ret += tab; ret += c; continue; } if(c == ']' && !betweenquotes) { ret += nl; ret += c; continue; } ret += c; } // i loop return ret; }


回答15:

I recommend using HighlightJS. It uses the same principle as the accepted answer, but works also for many other languages, and has many pre-defined colour schemes. If using RequireJS, you can generate a compatible module with

python3 tools/build.py -tamd json xml 

Generation relies on Python3 and Java. Add -n to generate a non-minified version.



回答16:

This is nice:

https://github.com/mafintosh/json-markup from mafintosh

const jsonMarkup = require('json-markup') const html = jsonMarkup({hello:'world'}) document.querySelector('#myElem').innerHTML = html 

HTML

If you're looking for a nice library to prettify json on a web page...

Prism.js is pretty good.

http://prismjs.com/

I found using JSON.stringify(obj, undefined, 2) to get the indentation, and then using prism to add a theme was a good approach.

If you're loading in JSON via an ajax call, then you can run one of Prism's utility methods to prettify

For example:

Prism.highlightAll() 


回答18:

Here is how you can print without using native function.

function pretty(ob, lvl = 0) {    let temp = [];    if(typeof ob === "object"){     for(let x in ob) {       if(ob.hasOwnProperty(x)) {         temp.push( getTabs(lvl+1) + x + ":" + pretty(ob[x], lvl+1) );       }     }     return "{\n"+ temp.join(",\n") +"\n" + getTabs(lvl) + "}";   }   else {     return ob;   }  }  function getTabs(n) {   let c = 0, res = "";   while(c++ < n)     res+="\t";   return res; }  let obj = {a: {b: 2}, x: {y: 3}}; console.log(pretty(obj));  /*   {     a: {       b: 2     },     x: {       y: 3     }   } */ 


回答19:

If you use net.sf.json, you can pretty print as follows (using a 4 space indentation):

JSONObject work = JSONObject.fromObject("{\"hi\":\"there\",\"more\":\"stuff\"}"); log.info("WORK="+work.toString(4)); 


回答20:

Use Newtonsoft.Json dll. this is work fine in IE and Chrome

put this code in your razor view

    if (Model.YourJsonSting!= null)         {             
                                   @JToken.Parse(Model.YourJsonSting).ToString(Formatting.Indented)                              
}


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!