using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.Reflection; using CYQ.Data.Table; using CYQ.Data.Tool; namespace CYQ.Data.Json { /// /// 分隔Json字符串为字典集合。 /// internal partial class JsonSplit { internal static bool IsJson(string json) { return IsJson(json, false); } internal static bool IsJson(string json, bool isStrictMode) { int errIndex; return IsJson(json, isStrictMode, out errIndex); } internal static bool IsJson(string json, bool isStrictMode, out int errIndex) { errIndex = 0; if (string.IsNullOrEmpty(json) || json.Length < 2 || ((json[0] != '{' && json[json.Length - 1] != '}') && (json[0] != '[' && json[json.Length - 1] != ']'))) { return false; } CharState cs = new CharState(isStrictMode); for (int i = 0; i < json.Length; i++) { //char c = ; if (cs.IsKeyword(json[i]) && cs.childrenStart)//设置关键符号状态。 { int err; int length = GetValueLength(isStrictMode, json, i, true, out err); cs.childrenStart = false; if (err > 0) { errIndex = i + err; return false; } i = i + length - 1; } if (cs.isError) { errIndex = i; return false; } } return !cs.arrayStart && !cs.jsonStart; //只要不是正常关闭,则失败 } internal static List> Split(string json) { return Split(json, 0); } ///// ///// 解析Json ///// ///// //internal static List> Split(string json, int topN) //{ // List> result = new List>(); // if (!string.IsNullOrEmpty(json)) // { // Dictionary dic = new Dictionary(16, StringComparer.OrdinalIgnoreCase); // int keyIndex = -1, valueIndex = -1; // int keyLength = 0, valueLength = 0; // CharState cs = new CharState(false); // try // { // #region 核心逻辑 // for (int i = 0; i < json.Length; i++) // { // char c = json[i]; // if (!cs.IsKeyword(c))//设置关键符号状态。 // { // if (cs.jsonStart)//Json进行中。。。 // { // if (cs.keyStart > 0) // { // if (keyIndex == -1) // { // keyIndex = i; // } // keyLength++; // } // else if (cs.valueStart > 0) // { // if (valueIndex == -1) // { // valueIndex = i; // } // valueLength++; // } // } // else if (!cs.arrayStart)//json结束,又不是数组,则退出。 // { // break; // } // } // else if (cs.childrenStart)//正常字符,值状态下。 // { // int temp; // valueLength = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍 // valueIndex = i; // cs.childrenStart = false; // cs.valueStart = 0; // cs.setDicValue = true; // i = i + valueLength - 1; // } // if (cs.setDicValue)//设置键值对。 // { // if (keyLength > 0) // { // string k = json.Substring(keyIndex, keyLength);// key.ToString(); // if (!dic.ContainsKey(k)) // { // string val = valueLength > 0 ? json.Substring(valueIndex, valueLength) : ""; //value.ToString(); // bool isNull = json[i - 5] == ':' && json[i] != '"' && valueLength == 4 && val == "null"; // if (isNull) // { // val = ""; // } // dic.Add(k, val); // } // } // cs.setDicValue = false; // keyIndex = valueIndex = -1; // keyLength = valueLength = 0; // } // if (!cs.jsonStart && dic.Count > 0) // { // result.Add(dic); // if (topN > 0 && result.Count >= topN) // { // return result; // } // if (cs.arrayStart)//处理数组。 // { // dic = new Dictionary(16, StringComparer.OrdinalIgnoreCase); // } // } // } // #endregion // } // catch (Exception err) // { // Log.Write(err, LogType.Error); // } // } // return result; //} /// /// 解析Json /// /// internal static List> Split(string json, int topN) { List> result = new List>(); if (!string.IsNullOrEmpty(json)) { Dictionary dic = new Dictionary(16, StringComparer.OrdinalIgnoreCase); //string key = string.Empty; StringBuilder key = new StringBuilder(32); StringBuilder value = new StringBuilder(); CharState cs = new CharState(false); try { #region 核心逻辑 for (int i = 0; i < json.Length; i++) { char c = json[i]; if (!cs.IsKeyword(c))//设置关键符号状态。 { if (cs.jsonStart)//Json进行中。。。 { if (cs.keyStart > 0) { key.Append(c); } else if (cs.valueStart > 0) { value.Append(c); } } else if (!cs.arrayStart)//json结束,又不是数组,则退出。 { break; } } else if (cs.childrenStart)//正常字符,值状态下。 { //string item = json.Substring(i); int temp; // int length = GetValueLength(false, json.Substring(i), false, out temp);//这里应该有优化的空间,传json和i,不重新生成string int length = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍 value.Length = 0; value.Append(json.Substring(i, length)); cs.childrenStart = false; cs.valueStart = 0; //cs.state = 0; cs.setDicValue = true; i = i + length - 1; } if (cs.setDicValue)//设置键值对。 { if (key.Length > 0) { string k = key.ToString(); if (!dic.ContainsKey(k)) { string val = value.ToString(); bool isNull = i > 4 && json[i - 5] == ':' && json[i] != '"' && value.Length == 4 && val == "null"; if (isNull) { val = ""; } dic.Add(k, val); } } cs.setDicValue = false; key.Length = 0; value.Length = 0; } if (!cs.jsonStart && dic.Count > 0) { result.Add(dic); if (topN > 0 && result.Count >= topN) { return result; } if (cs.arrayStart)//处理数组。 { dic = new Dictionary(16, StringComparer.OrdinalIgnoreCase); } } } #endregion } catch (Exception err) { Log.Write(err, LogType.Error); } finally { key = null; value = null; } } return result; } /* /// /// 获取值的长度(当Json值嵌套以"{"或"["开头时) /// private static int GetValueLength(bool isStrictMode, string json, bool breakOnErr, out int errIndex) { errIndex = 0; int len = json.Length - 1; if (!string.IsNullOrEmpty(json)) { CharState cs = new CharState(isStrictMode); char c; for (int i = 0; i < json.Length; i++) { c = json[i]; if (!cs.IsKeyword(c))//设置关键符号状态。 { if (!cs.jsonStart && !cs.arrayStart)//json结束,又不是数组,则退出。 { break; } } else if (cs.childrenStart)//正常字符,值状态下。 { int length = GetValueLength(isStrictMode, json.Substring(i), breakOnErr, out errIndex);//递归子值,返回一个长度。。。 cs.childrenStart = false; cs.valueStart = 0; //cs.state = 0; i = i + length - 1; } if (breakOnErr && cs.isError) { errIndex = i; return i; } if (!cs.jsonStart && !cs.arrayStart)//记录当前结束位置。 { len = i + 1;//长度比索引+1 break; } } } return len; } */ /// /// 获取值的长度(当Json值嵌套以"{"或"["开头时),【优化后】 /// private static int GetValueLength(bool isStrictMode, string json, int startIndex, bool breakOnErr, out int errIndex) { errIndex = 0; int len = json.Length - 1 - startIndex; if (!string.IsNullOrEmpty(json)) { CharState cs = new CharState(isStrictMode); char c; for (int i = startIndex; i < json.Length; i++) { c = json[i]; if (!cs.IsKeyword(c))//设置关键符号状态。 { if (!cs.jsonStart && !cs.arrayStart)//json结束,又不是数组,则退出。 { break; } } else if (cs.childrenStart)//正常字符,值状态下。 { int length = GetValueLength(isStrictMode, json, i, breakOnErr, out errIndex);//递归子值,返回一个长度。。。 cs.childrenStart = false; cs.valueStart = 0; i = i + length - 1; } if (breakOnErr && cs.isError) { errIndex = i; return i - startIndex; } if (!cs.jsonStart && !cs.arrayStart)//记录当前结束位置。 { len = i + 1;//长度比索引+1 len = len - startIndex; break; } } } return len; } #region 扩展转实体T internal static T ToEntity(string json, EscapeOp op) { List t = ToList(json, 0, op); if (t.Count > 0) { return t[0]; } return default(T); } internal static List ToList(string json, int topN, EscapeOp op) { Type t = typeof(T); if (t.IsValueType || t.Name == "String") { return new MDataRow().GetObj(typeof(List), json) as List; } List result = new List(); if (!string.IsNullOrEmpty(json) && json.Length > 4) { // object entity = Activator.CreateInstance(t); T entity = Activator.CreateInstance(); bool hasSetValue = false; List pInfoList = ReflectTool.GetPropertyList(t); List fInfoList = ReflectTool.GetFieldList(t); //string key = string.Empty; StringBuilder key = new StringBuilder(32); StringBuilder value = new StringBuilder(); CharState cs = new CharState(false); try { #region 核心逻辑 char c; for (int i = 0; i < json.Length; i++) { c = json[i]; if (!cs.IsKeyword(c))//设置关键符号状态。 { if (cs.jsonStart)//Json进行中。。。 { if (cs.keyStart > 0) { key.Append(c); } else if (cs.valueStart > 0) { value.Append(c); } } else if (!cs.arrayStart)//json结束,又不是数组,则退出。 { break; } } else if (cs.childrenStart)//正常字符,值状态下。 { int temp; int length = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍 value.Length = 0; value.Append(json.Substring(i, length)); cs.childrenStart = false; cs.valueStart = 0; cs.setDicValue = true; i = i + length - 1; } if (cs.setDicValue)//设置键值对。 { if (key.Length > 0) { string k = key.ToString(); string val = value.ToString();//.TrimEnd('\r', '\n', '\t'); bool isNull = i > 4 && json[i - 5] == ':' && json[i] != '"' && val.Length == 4 && val == "null"; if (isNull) { val = ""; } else { val = JsonHelper.UnEscape(val, op); } bool hasProperty = false; object o = val; foreach (PropertyInfo p in pInfoList) { if (String.Compare(p.Name, k, StringComparison.OrdinalIgnoreCase) == 0) { hasProperty = true; if (p.CanWrite) { if (p.PropertyType.Name != "String") { o = ConvertTool.ChangeType(val, p.PropertyType); } p.SetValue(entity, o, null); hasSetValue = true; } break; } } if (!hasProperty && fInfoList.Count > 0) { foreach (FieldInfo f in fInfoList) { if (String.Compare(f.Name, k, StringComparison.OrdinalIgnoreCase) == 0) { if (f.FieldType.Name != "String") { o = ConvertTool.ChangeType(val, f.FieldType); } f.SetValue(entity, o); hasSetValue = true; break; } } } } cs.setDicValue = false; key.Length = 0; value.Length = 0; } if (!cs.jsonStart && hasSetValue) { result.Add(entity); if (topN > 0 && result.Count >= topN) { return result; } if (cs.arrayStart)//处理数组。 { entity = Activator.CreateInstance(); hasSetValue = false; } } } #endregion } catch (Exception err) { Log.Write(err, LogType.Error); } finally { key = null; value = null; } } return result; } /// /// 支持转换:实体或实体列表二合一 /// internal static object ToEntityOrList(Type t, string json, EscapeOp op) { Type toType = t; object listObj = null; MethodInfo method = null; if (t.IsGenericType && (t.Name.StartsWith("List") || t.Name.StartsWith("IList") || t.Name.StartsWith("MList"))) { Type[] paraTypeList = null; ReflectTool.GetArgumentLength(ref t, out paraTypeList); toType = paraTypeList[0]; if (toType.IsValueType || toType.Name == "String") { return new MDataRow().GetObj(t, json); } listObj = Activator.CreateInstance(t);//创建实例 method = t.GetMethod("Add"); } if (!string.IsNullOrEmpty(json)) { object entity = Activator.CreateInstance(toType); bool hasSetValue = false; List pInfoList = ReflectTool.GetPropertyList(toType); List fInfoList = ReflectTool.GetFieldList(toType); //string key = string.Empty; StringBuilder key = new StringBuilder(32); StringBuilder value = new StringBuilder(); CharState cs = new CharState(false); try { #region 核心逻辑 char c; for (int i = 0; i < json.Length; i++) { c = json[i]; if (!cs.IsKeyword(c))//设置关键符号状态。 { if (cs.jsonStart)//Json进行中。。。 { if (cs.keyStart > 0) { key.Append(c); } else if (cs.valueStart > 0) { value.Append(c); } } else if (!cs.arrayStart)//json结束,又不是数组,则退出。 { break; } } else if (cs.childrenStart)//正常字符,值状态下。 { int temp; int length = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍 value.Length = 0; value.Append(json.Substring(i, length)); cs.childrenStart = false; cs.valueStart = 0; cs.setDicValue = true; i = i + length - 1; } if (cs.setDicValue)//设置键值对。 { if (key.Length > 0) { string k = key.ToString(); string val = value.ToString();//.TrimEnd('\r', '\n', '\t'); bool isNull = i > 4 && json[i - 5] == ':' && json[i] != '"' && val.Length == 4 && val == "null"; if (isNull) { val = ""; } else { val = JsonHelper.UnEscape(val, op); } bool hasProperty = false; object o = val; foreach (PropertyInfo p in pInfoList) { if (String.Compare(p.Name, k, StringComparison.OrdinalIgnoreCase) == 0) { hasProperty = true; if (p.CanWrite) { if (p.PropertyType.Name != "String") { o = ConvertTool.ChangeType(val, p.PropertyType); } p.SetValue(entity, o, null); hasSetValue = true; } break; } } if (!hasProperty && fInfoList.Count > 0) { foreach (FieldInfo f in fInfoList) { if (String.Compare(f.Name, k, StringComparison.OrdinalIgnoreCase) == 0) { if (f.FieldType.Name != "String") { o = ConvertTool.ChangeType(val, f.FieldType); } f.SetValue(entity, o); hasSetValue = true; break; } } } } cs.setDicValue = false; key.Length = 0; value.Length = 0; } if (!cs.jsonStart && hasSetValue) { if (method != null) { method.Invoke(listObj, new object[] { entity }); } else { return entity; } if (cs.arrayStart)//处理数组。 { entity = Activator.CreateInstance(toType); hasSetValue = false; } } } #endregion } catch (Exception err) { Log.Write(err, LogType.Error); } finally { key = null; value = null; } } return listObj; } #endregion } internal partial class JsonSplit { /// /// 将json数组分成字符串List /// /// ["a,","bbb,,"] /// internal static List SplitEscapeArray(string jsonArray) { if (!string.IsNullOrEmpty(jsonArray)) { jsonArray = jsonArray.Trim(' ', '[', ']');//["a,","bbb,,"] List list = new List(); if (jsonArray.Length > 0) { string[] items = jsonArray.Split(','); string objStr = string.Empty; foreach (string value in items) { string item = value.Trim('\r', '\n', '\t', ' '); if (objStr == string.Empty) { objStr = item; } else { objStr += "," + item; } char firstChar = objStr[0]; if (firstChar == '"' || firstChar == '\'') { //检测双引号的数量 if (GetCharCount(objStr, firstChar) % 2 == 0)//引号成双 { list.Add(objStr.Trim(firstChar).Replace("\\" + firstChar, firstChar.ToString())); objStr = string.Empty; } } else { list.Add(item); objStr = string.Empty; } } } return list; } return null; } /// /// 获取字符在字符串出现的次数 /// /// /// private static int GetCharCount(string item, char c) { int num = 0; for (int i = 0; i < item.Length; i++) { if (item[i] == '\\') { i++; } else if (item[i] == c) { num++; } } return num; } } }