测试JSON
{"took":1,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":2,"relation":"eq"},"max_score":1,"hits":[{"_index":"stu","_type":"_doc","_id":"1","_score":1,"_source":{"id":1,"name":"Student1","email":"[email protected]"}},{"_index":"stu","_type":"_doc","_id":"2","_score":1,"_source":{"id":2,"name":"Student2","email":"[email protected]"}}]},"aggregations":{"group_by_word_count":{"doc_count_error_upper_bound":0,"sum_other_doc_count":0,"buckets":[{"key":"Student1","doc_count":1},{"key":"Student2","doc_count":1}]}}}View Code
想要实现的结果
{ "took": 1, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 2, "relation": "eq" }, "max_score": 1, "hits": [ { "_index": "stu", "_type": "_doc", "_id": "1", "_score": 1, "_source": { "id": 1, "name": "Student1", "email": "[email protected]" } }, { "_index": "stu", "_type": "_doc", "_id": "2", "_score": 1, "_source": { "id": 2, "name": "Student2", "email": "[email protected]" } } ] }, "aggregations": { "group_by_word_count": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "Student1", "doc_count": 1 }, { "key": "Student2", "doc_count": 1 } ] } } }View Code
C# 后端的解决方案:
0X01.使用 Newtonsoft.Json
public static void Test1() { string filePath = "TestFile/TextFile1.txt"; if (File.Exists(filePath)) { string jsonStr = File.ReadAllText(filePath); JsonSerializer serializer = new JsonSerializer(); TextReader tr = new StringReader(jsonStr); JsonTextReader jtr = new JsonTextReader(tr); object obj = serializer.Deserialize(jtr); if (obj != null) { StringWriter textWriter = new StringWriter(); JsonTextWriter jsonWriter = new JsonTextWriter(textWriter) { Formatting = Newtonsoft.Json.Formatting.Indented,//格式化缩进 Indentation = 4,//缩进字符数 IndentChar = ' '//缩进字符 }; serializer.Serialize(jsonWriter, obj); string res = textWriter.ToString(); Console.WriteLine(res); } } }
0X02.使用自定义 格式化排版
public static void Test3() { string filePath = "TestFile/TextFile1.txt"; if (File.Exists(filePath)) { string jsonStr = File.ReadAllText(filePath); var obj = JsonHelper.JsonToObject<Dictionary<string,object>>(jsonStr); string json = JsonHelper.ObjectToJson(obj); Console.WriteLine(json); } } // 将序列化之后的 json 字符串进行格式化 public static string JsonFormat(string json) { int level = 0; var jsonArr = json.ToArray(); StringBuilder jsonStr = new StringBuilder(1024); string _nt = "\r\n"; for (int i = 0; i < json.Length; i++) { char c = jsonArr[i]; if (level > 0 && '\n' == jsonStr.ToString().ToArray()[jsonStr.Length - 1]) { jsonStr.Append(TreeLevel(level)); } switch (c) { case '[': jsonStr.Append(c + _nt); level++; break; case ',': jsonStr.Append(c + _nt); break; case ':': jsonStr.Append(c + " "); break; case ']': level--; jsonStr.Append(_nt); jsonStr.Append(TreeLevel(level)); jsonStr.Append(c); break; case '{': jsonStr.Append(c + _nt); level++; break; case '}': level--; jsonStr.Append(_nt); jsonStr.Append(TreeLevel(level)); jsonStr.Append(c); break; default: jsonStr.Append(c); break; } } return jsonStr.ToString(); } // 设置缩进 private static string TreeLevel(int level) { string leaf = string.Empty; for (int t = 0; t < level; t++) { leaf += " "; } return leaf; }
以上示例 参照: https://www.cnblogs.com/Katakana/p/14268170.html
0X03.使用 System.Text.Json
using Common.JsonConverter; using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Json.Nodes; namespace Common { /// <summary> /// json序列化,反序列化帮助类 /// </summary> public class JsonHelper { private static readonly JsonSerializerOptions objectToJsonOptions; private static readonly JsonSerializerOptions jsonToObjectOptions; static JsonHelper() { objectToJsonOptions = new() { WriteIndented = true, //关闭默认转义 Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, //启用驼峰格式 PropertyNamingPolicy = JsonNamingPolicy.CamelCase, }; objectToJsonOptions.Converters.Add(new DateTimeConverter()); objectToJsonOptions.Converters.Add(new DateTimeOffsetConverter()); objectToJsonOptions.Converters.Add(new LongConverter()); jsonToObjectOptions = new() { //启用大小写不敏感 PropertyNameCaseInsensitive = true }; jsonToObjectOptions.Converters.Add(new DateTimeConverter()); jsonToObjectOptions.Converters.Add(new DateTimeOffsetConverter()); jsonToObjectOptions.Converters.Add(new LongConverter()); } /// <summary> /// 通过 Key 获取 Value /// </summary> /// <returns></returns> public static string GetValueByKey(string json, string key) { try { using JsonDocument doc = JsonDocument.Parse(json); return doc.RootElement.GetProperty(key).ToString(); } catch { return null; } } /// <summary> /// 对象 转 Json /// </summary> /// <param name="obj">对象</param> /// <returns>JSON格式的字符串</returns> public static string ObjectToJson(object obj) { return System.Text.Json.JsonSerializer.Serialize(obj, objectToJsonOptions); } /// <summary> /// Json 转 对象 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="json">JSON文本</param> /// <returns>指定类型的对象</returns> public static T JsonToObject<T>(string json) { return System.Text.Json.JsonSerializer.Deserialize<T>(json, jsonToObjectOptions)!; } /// <summary> /// 没有 Key 的 Json 转 List /// </summary> /// <param name="json"></param> /// <returns></returns> public static JsonNode JsonToArrayList(string json) { var jsonNode = JsonNode.Parse(json); return jsonNode; } } }JsonHelper
using System.Text.Json; using System.Text.Json.Serialization; namespace Common.JsonConverter { /// <summary> /// 时间日期格式化 /// </summary> public class DateTimeConverter : System.Text.Json.Serialization.JsonConverter<DateTime> { private readonly string formatString; /// <summary> /// 时间日期格式化 /// </summary> public DateTimeConverter() { formatString = "yyyy/MM/dd HH:mm:ss"; } /// <summary> /// 时间日期格式化 /// </summary> /// <param name="inFormatString"></param> public DateTimeConverter(string inFormatString) { formatString = inFormatString; } /// <summary> /// 读 /// </summary> /// <param name="reader"></param> /// <param name="typeToConvert"></param> /// <param name="options"></param> /// <returns></returns> public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { if (DateTime.TryParse(reader.GetString(), out DateTime date)) { return date; } } return reader.GetDateTime(); } /// <summary> /// 写 /// </summary> /// <param name="writer"></param> /// <param name="value"></param> /// <param name="options"></param> public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString(formatString)); } } }JsonConverter.DateTimeConverter
using System.Text.Json; using System.Text.Json.Serialization; namespace Common.JsonConverter { /// <summary> /// 带毫秒的时间格式化 /// </summary> public class DateTimeOffsetConverter : System.Text.Json.Serialization.JsonConverter<DateTimeOffset> { private readonly string formatString; /// <summary> /// /// </summary> public DateTimeOffsetConverter() { formatString = "yyyy/MM/dd HH:mm:ss zzz"; } /// <summary> /// 带毫秒的时间格式化 /// </summary> /// <param name="inFormatString"></param> public DateTimeOffsetConverter(string inFormatString) { formatString = inFormatString; } /// <summary> /// 读 /// </summary> /// <param name="reader"></param> /// <param name="typeToConvert"></param> /// <param name="options"></param> /// <returns></returns> public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { if (DateTimeOffset.TryParse(reader.GetString(), out DateTimeOffset date)) { return date; } } return reader.GetDateTimeOffset(); } /// <summary> /// 写 /// </summary> /// <param name="writer"></param> /// <param name="value"></param> /// <param name="options"></param> public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString(formatString)); } } }JsonConverter.DateTimeOffsetConverter
using System.Text.Json; using System.Text.Json.Serialization; namespace Common.JsonConverter { /// <summary> /// 长整型id格式化 /// </summary> public class LongConverter : System.Text.Json.Serialization.JsonConverter<long> { /// <summary> /// 读 /// </summary> /// <param name="reader"></param> /// <param name="typeToConvert"></param> /// <param name="options"></param> /// <returns></returns> public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { if (long.TryParse(reader.GetString(), out long l)) { return l; } } return reader.GetInt64(); } /// <summary> /// 写 /// </summary> /// <param name="writer"></param> /// <param name="value"></param> /// <param name="options"></param> public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString()); } } }JsonConverter.LongConverter
using System.Text.Json; using System.Text.Json.Serialization; namespace Common.JsonConverter { /// <summary> /// 可空对象序列化 /// </summary> public class NullableStructConverterFactory : JsonConverterFactory { /// <summary> /// 检查是否有值 /// </summary> /// <param name="typeToConvert"></param> /// <returns></returns> public override bool CanConvert(Type typeToConvert) { if (typeToConvert.GetProperty("HasValue") != null) { return true; } return false; } /// <summary> /// 创建格式化设置 /// </summary> /// <param name="typeToConvert"></param> /// <param name="options"></param> /// <returns></returns> public override System.Text.Json.Serialization.JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { var converterType = typeof(NullableConverter<>).MakeGenericType(typeToConvert.GenericTypeArguments[0]); return (System.Text.Json.Serialization.JsonConverter)Activator.CreateInstance(converterType)!; } /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> private class NullableConverter<T> : System.Text.Json.Serialization.JsonConverter<T?> where T : struct { /// <summary> /// 读 /// </summary> /// <param name="reader"></param> /// <param name="typeToConvert"></param> /// <param name="options"></param> /// <returns></returns> public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { if (string.IsNullOrEmpty(reader.GetString()) || string.IsNullOrWhiteSpace(reader.GetString())) { return null; } } return System.Text.Json.JsonSerializer.Deserialize<T>(ref reader, options); } /// <summary> /// 写 /// </summary> /// <param name="writer"></param> /// <param name="value"></param> /// <param name="options"></param> public override void Write(Utf8JsonWriter writer, T? value, JsonSerializerOptions options) { var tempOptions = new JsonSerializerOptions(options); var thisFactory = new NullableStructConverterFactory().ToString(); tempOptions.Converters.Remove(options.Converters.FirstOrDefault(t => t.ToString() == thisFactory)!); System.Text.Json.JsonSerializer.Serialize(writer, value, tempOptions); } } } }JsonConverter.NullableStructConverterFactory
调用方式为:
public static void Test3() { string filePath = "TestFile/TextFile1.txt"; if (File.Exists(filePath)) { string jsonStr = File.ReadAllText(filePath); var obj = JsonHelper.JsonToObject<Dictionary<string,object>>(jsonStr); string json = JsonHelper.ObjectToJson(obj); Console.WriteLine(json); } }
0X04.前端js 中格式化
先看样例,左侧输入json 源码, 点击 美化,生成 右边的html 格式化后的代码用于展示
下面是美化的带样式的高亮效果 ,以及 不带高亮的效果
直接上代码:
<template> <div class="page-container"> <div class="flex-row"> <div class="left-content"> <div class="flex-row"> <div class="wrap"> <monaco-edito ref="jsonOri" height="400px" language="html" pmsg="json字符串" :value="code_jsonOri" width="750px" /> </div> <div class="wrap"> <monaco-edito ref="jsonNew" height="400px" language="html代码" pmsg="html" :value="code_jsonNew" width="750px" /> </div> </div> </div> </div> <div class="flex-row"> <div class="right-content"> <button @click="beauClick">美化</button> <button @click="clearClick">清空</button> <!-- <button @click="formClick">格式化</button> --> </div> </div> <div class="flex-row"> <div class="wrap"> <p style="background: #ffeebb"> <span style="color: rgb(154, 72, 192)">着色样式</span> </p> <div class="right-content"> <div id="Canvas" class="json_beautiful" style="width: 750px" v-html="code_beau_html" ></div> </div> </div> <div class="wrap"> <p style="background: rgb(60, 228, 125)"> <span style="color: rgb(154, 72, 192)">默认样式</span> </p> <div class="right-content"> <div style="width: 750px" v-html="code_newHtml"></div> </div> </div> </div> </div> </template> <script> import MonacoEdito from '@/components/monacoEditor/index.vue' export default { name: 'App', components: { MonacoEdito, }, data() { return { tabkg: ' ', code_jsonOri: ``, code_jsonNew: '', code_newHtml: '', code_beau_html: '', } }, methods: { runCode() { // let json_ori = this.$refs.jsonOri.monacoEditor.getValue() // let json_new = this.$refs.jsonNew.monacoEditor.getValue() }, clearClick() { this.code_jsonOri = '' this.code_jsonNew = '' this.code_newHtml = '' this.code_beau_html = '' this.$refs.jsonNew.monacoEditor.setValue('') this.$refs.jsonOri.monacoEditor.setValue('') }, beauClick() { let html = '' let json = this.$refs.jsonOri.monacoEditor.getValue() try { if (json == '') { json = '""' } let obj = eval('[' + json + ']') html = this.ProcessObject(obj[0], 0, false, false, false) if ( this.isNullOrEmpty(html) || html === '<span class=\'String\'>""</span>' || html.length <= 10 ) { console.log(1111) this.code_beau_html = '' this.code_newHtml = '' this.$refs.jsonNew.monacoEditor.setValue('') } else { console.log(2222) let showHtml = "<PRE class='CodeContainer'>" + html + '</PRE>' this.code_beau_html = showHtml this.code_newHtml = showHtml this.$refs.jsonNew.monacoEditor.setValue(html) } } catch (e) { alert('json语法错误,不能格式化。错误信息:\n' + e.message) document.getElementById('Canvas').innerHTML = '' } }, formClick() { let json = this.$refs.jsonOri.monacoEditor.getValue() let res = this.formatJson(json) this.$refs.jsonNew.monacoEditor.setValue(res) }, formatJson(json, options) { const _this = this let reg = null, formatted = '', pad = 0, PADDING = ' ' options = options || {} options.newlineAfterColonIfBeforeBraceOrBracket = options.newlineAfterColonIfBeforeBraceOrBracket === true ? true : false options.spaceAfterColon = options.spaceAfterColon === false ? false : true if (typeof json !== 'string') { json = JSON.stringify(json) } else { json = JSON.parse(json) json = JSON.stringify(json) } reg = /([\\{\\}])/g json = json.replace(reg, '\r\n$1\r\n') reg = /([\\[\]])/g json = json.replace(reg, '\r\n$1\r\n') reg = /(\\,)/g json = json.replace(reg, '$1\r\n') reg = /(\r\n\r\n)/g json = json.replace(reg, '\r\n') reg = /\r\n\\,/g json = json.replace(reg, ',') if (!options.newlineAfterColonIfBeforeBraceOrBracket) { reg = /\\:\r\n\{/g json = json.replace(reg, ':{') reg = /\\:\r\n\[/g json = json.replace(reg, ':[') } if (options.spaceAfterColon) { reg = /\\:/g json = json.replace(reg, ':') } json.split('\r\n').forEach(function (node, index) { //console.log(node); _this.ignorLog(index) let i = 0, indent = 0, padding = '' if (node.match(/\{$/) || node.match(/\[$/)) { indent = 1 } else if (node.match(/\}/) || node.match(/\]/)) { if (pad !== 0) { pad -= 1 } } else { indent = 0 } for (i = 0; i < pad; i++) { padding += PADDING } formatted += padding + node + '\r\n' pad += indent }) return formatted }, ProcessObject(obj, indent, addComma, isArray, isPropertyContent) { let html = '' let comma = addComma ? "<span class='Comma'>,</span> " : '' let type = typeof obj if (this.IsArray(obj)) { if (obj.length == 0) { html += this.GetRow( indent, "<span class='ArrayBrace'>[ ]</span>" + comma, isPropertyContent ) } else { html += this.GetRow( indent, "<span class='ArrayBrace'>[</span>", isPropertyContent ) for (let i = 0; i < obj.length; i++) { html += this.ProcessObject( obj[i], indent + 1, i < obj.length - 1, true, false ) } html += this.GetRow( indent, "<span class='ArrayBrace'>]</span>" + comma ) } } else { if (type == 'object' && obj == null) { html += this.FormatLiteral( 'null', '', comma, indent, isArray, 'Null' ) } else { if (type == 'object') { let numProps = 0 for (let k in obj) { this.ignorLog(k) numProps++ } if (numProps == 0) { html += this.GetRow( indent, "<span class='ObjectBrace'>{ }</span>" + comma, isPropertyContent ) } else { html += this.GetRow( indent, "<span class='ObjectBrace'>{</span>", isPropertyContent ) let j = 0 for (let prop in obj) { html += this.GetRow( indent + 1, '<span class="PropertyName">"' + prop + '"</span>: ' + this.ProcessObject( obj[prop], indent + 1, ++j < numProps, false, true ) ) } html += this.GetRow( indent, "<span class='ObjectBrace'>}</span>" + comma ) } } else { if (type == 'number') { html += this.FormatLiteral( obj, '', comma, indent, isArray, 'Number' ) } else { if (type == 'boolean') { html += this.FormatLiteral( obj, '', comma, indent, isArray, 'Boolean' ) } else { if (type == 'function') { obj = this.FormatFunction(indent, obj) html += this.FormatLiteral( obj, '', comma, indent, isArray, 'Function' ) } else { if (type == 'undefined') { html += this.FormatLiteral( 'undefined', '', comma, indent, isArray, 'Null' ) } else { html += this.FormatLiteral( obj, '"', comma, indent, isArray, 'String' ) } } } } } } } return html }, FormatLiteral(literal, quote, comma, indent, isArray, style) { if (typeof literal == 'string') { literal = literal.split('<').join('<').split('>').join('>') } let str = "<span class='" + style + "'>" + quote + literal + quote + comma + '</span>' if (isArray) { str = this.GetRow(indent, str) } return str }, FormatFunction(indent, obj) { let tabs = '' for (let i = 0; i < indent; i++) { tabs += this.tabkg } let funcStrArray = obj.toString().split('\n') let str = '' for (let i = 0; i < funcStrArray.length; i++) { str += (i == 0 ? '' : tabs) + funcStrArray[i] + '\n' } return str }, GetRow(indent, data, isPropertyContent) { let tabs = '' for (let i = 0; i < indent && !isPropertyContent; i++) { tabs += this.tabkg } if ( data != null && data.length > 0 && data.charAt(data.length - 1) != '\n' ) { data = data + '\n' } return tabs + data }, }, } </script> <style lang="scss"> .json_beautiful { pre { font-family: 'consolas'; color: rgb(60, 228, 125); } .Canvas { font: 14px/18px 'consolas'; background-color: #db2727; color: #000000; border: solid 1px #cecece; } .ObjectBrace { color: #00aa00; font-weight: bold; } .ArrayBrace { color: #0033ff; font-weight: bold; } .PropertyName { color: #cc0000; font-weight: bold; } .String { color: #007777; } .Number { color: #aa00aa; } .Boolean { color: #0000ff; } .Function { color: #aa6633; text-decoration: italic; } .Null { color: #0000ff; } .Comma { color: #000000; font-weight: bold; } PRE.CodeContainer { margin-top: 0px; margin-bottom: 0px; } } </style> <style scoped> * { padding: 0; margin: 0; } .flex-row { display: flex; flex-direction: row; } .result { /* width: 100%; height: 100%; */ border: 1px solid #ccc; width: 100%; height: 500px; } .left-content { width: 1000px; } .right-content { margin-left: 15px; padding: 10px; width: 100%; /* background: red; */ } .wrap { display: flex; flex-direction: column; } .wrap p { padding: 5px; text-align: center; font-size: 18px; font-weight: bold; color: #fff; } .right-content p { margin: 5px 0; } button { display: inline-block; line-height: 1; white-space: nowrap; cursor: pointer; background: #409eff; border: 1px solid #409eff; color: #ffffff; text-align: center; box-sizing: border-box; outline: none; margin: 0; transition: 0.1s; font-weight: 500; padding: 12px 20px; font-size: 14px; border-radius: 4px; } </style>Vue JSON美化
本文涉及到的源码: 见附件 点击下载
标签:obj,string,json,JSON,html,indent,格式化,数据,public From: https://www.cnblogs.com/mjxxsc/p/17464260.html