C# 自定义Json解析工具
生活随笔
收集整理的這篇文章主要介紹了
C# 自定义Json解析工具
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
需求
需求內容
還是上一篇公司那個java轉C#的需求,其中socket是json格式的。需求中的這個json需要能夠動態增刪json數據中的元素:每條數據的key和value都是動態定義的,解析出來才知道收到哪些key和value,而且有些value本身又是json數據,也就是說json數據嵌套。
需求并不復雜,但是找了找并沒有找到好的json序列化和反序列化工具,.NET自帶的運行時序列化和反序列化json工具(System.Runtime.Serialization.Json;)轉換出來的結果并不符合要求。想來想去還是自己寫一個,權當練手。
需求分析
既然不依靠插件就得手動分析字符串進行逐字符拆分了。這讓我想起了計算機對數學運算表達式進行運算優先級解析并得出運算結果的例子。具體的實現過程已經忘了,大致記得是使用堆棧來對數據和運算符的順序進行分離保存和運算直至最終結果。json文件雖然沒有太多的優先級,但是{},“”,:以及反斜杠和逗號都對數據進行了分類和層級處理。
我們來看看這個json的字符串格式:
從以上格式可以看出:
- 每個‘{’都有一個對應的‘}’,左右括號之間的數據可以看做一個json數據塊。于是我們可以用Stack來處理:遇到‘{’進棧,遇到‘}’出棧,直至Stack中的元素數量為0,這樣開從開始的‘{’到結束的‘}’之間的數據就是一個json數據塊
- ‘,’分隔json鍵值對
- ‘:’分隔每個鍵值對的“Key“和”Value“
- ‘\’作為轉義字符,讀取的時候忽略,輸出的時候加在內層json的符號前
- 所有的鍵值對使用隊列存儲起來,然后遇到‘:‘放出一個鍵,遇到’,‘或者json塊結尾放出一個值直至結束
實現
廢話不多說,直接上代碼,代碼比較簡單,根據上述分析自己體會。
public class Json {public Json() { }public Json(string firstname, object lastname){this.FirstName = firstname;this.LastName = lastname;}public string FirstName { get; set; }public object LastName { get; set; } } public class JSONHelper {public static List<Json> Serialize(string str, Queue<object> quStr=null){if (quStr == null) {string[] sArray = str.Split(new char[6] { '{', '}', ',', ':', '\"', '\\' }, StringSplitOptions.RemoveEmptyEntries);quStr = new Queue<object>();for (int i = 0; i < sArray.Length; i++)if (sArray[i] != "\""){int a;if (int.TryParse(sArray[i], out a))quStr.Enqueue(a);elsequStr.Enqueue(sArray[i]);}}List<Json> json = new List<Json>();json.Add(new Json());for (int i = 0; i < str.Length; i++){switch (str[i]){case '{':Stack<char> parentheses = new Stack<char>();parentheses.Push('{');int j = i;while (parentheses.Count > 0)//找到與之匹配的反括號的位置{j++;if (str[j] == '}')parentheses.Pop();if (str[j] == '{')parentheses.Push('{');}if (json[json.Count - 1].FirstName == null)json = Serialize(str.Substring(i + 1, j - i - 1), quStr);elsejson[json.Count - 1].LastName = Serialize(str.Substring(i + 1, j - i - 1), quStr);//解析括號里的json數據i = j;break;case ',':json[json.Count - 1].LastName = quStr.Dequeue();json.Add(new Json());continue;case ':':json[json.Count - 1].FirstName = quStr.Dequeue().ToString();continue;case '\\': continue;case '\"': continue;default: continue;}}if (quStr.Count > 0)json[json.Count - 1].LastName = quStr.Dequeue();return json;}public static string DeSerialize(List<Json> json, string mark = "\""){if (json == null)return null;Queue<object> quStr = new Queue<object>();quStr.Enqueue("{");for (int i = 0; i < json.Count; i++){quStr.Enqueue(mark + json[i].FirstName + mark);quStr.Enqueue(":");if (json[i].LastName.GetType() == json.GetType())quStr.Enqueue(string.Format("{0}{1}{2}", mark, DeSerialize(json[i].LastName as List<Json>, "\\\""), mark));//解析json子節點的內容else if (json[i].LastName.GetType() == (":").GetType())quStr.Enqueue(mark + json[i].LastName + mark);elsequStr.Enqueue((int)json[i].LastName);if (i < json.Count - 1)quStr.Enqueue(",");}quStr.Enqueue("}");object[] sarr = new object[quStr.Count];for (int j = 0; j < sarr.Length; j++)sarr[j] = quStr.Dequeue();return string.Join("", sarr);} }轉載請注明出處:http://blog.csdn.net/ylbs110/article/details/51280370
測試
測試代碼
string str = "{\"head\":\"setValue\",\"info\":\"{\"value\":10,\"key\":\"3DDepth\"}\"}"; List<Json> json = JSONHelper.Serialize(str); foreach (Json s in json){Console.WriteLine(s.FirstName);if (s.LastName.GetType() == json.GetType()){List<Json> jsons = s.LastName as List<Json>;foreach (Json ss in jsons){Console.WriteLine(" " + ss.FirstName);Console.WriteLine(" " + ss.LastName);}}elseConsole.WriteLine(s.LastName); } Console.WriteLine(JSONHelper.DeSerialize(json));輸出
head setValue infovalue10key3DDepth {"head":"setValue","info":"{\"value\":10,\"key\":\"3DDepth\"}"}總結
以上是生活随笔為你收集整理的C# 自定义Json解析工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EntityFramework的安装
- 下一篇: 嵌入式开发概述(树莓派介绍)