/// <summary> /// 设置子对象 /// </summary> /// <param name="key"></param> /// <param name="unit"></param> protected override void OnSetChildItem(string key, JsonUnit unit) { // 当子对象已经存在,则先销毁原有对象 if (_list.ContainsKey(key)) { _list[key].Dispose(); } _list[key] = unit; }
/// <summary> /// 设置索引对象 /// </summary> /// <param name="index"></param> /// <param name="unit"></param> protected override void OnSetArrayItem(int index, JsonUnit unit) { if (index < _list.Count) { // 索引存在,则释放原有的资源 _list[index].Dispose(); _list[index] = unit; } else { // 索引不存在,则添加索引至当前索引值 for (int i = _list.Count; i < index; i++) { _list.Add(new JsonString(this)); } _list.Add(unit); } }
/// <summary> /// 对象实例化 /// </summary> public JsonNumber(JsonUnit parent) : base(UnitType.Number, parent) { this.Value = 0; }
/// <summary> /// 对象实例化 /// </summary> public JsonBoolean(JsonUnit parent) : base(UnitType.Number, parent) { this.Value = false; }
/// <summary> /// 对象实例化 /// </summary> public JsonArray(JsonUnit parent = null) : base(UnitType.Array, parent) { _list = new List <JsonUnit>(); }
/// <summary> /// 对象实例化 /// </summary> public JsonString(JsonUnit parent) : base(UnitType.String, parent) { this.Value = null; }
/// <summary> /// 对象实例化 /// </summary> public JsonObject(JsonUnit parent = null) : base(UnitType.Object, parent) { _list = new KeyValues <JsonUnit>(); }
/// <summary> /// 对象实例化 /// </summary> /// <param name="type"></param> /// <param name="parent"></param> public JsonUnit(UnitType type, JsonUnit parent = null) { this.UnitType = type; this.Parent = parent; }
/// <summary> /// 设置子对象 /// </summary> /// <param name="key"></param> /// <param name="unit"></param> /// <returns></returns> protected virtual void OnSetChildItem(string key, JsonUnit unit) { throw new Exception($"{this.UnitType.ToString()}类型尚未支持设置索引子对象"); }
/// <summary> /// 设置索引对象 /// </summary> /// <param name="index"></param> /// <param name="unit"></param> /// <returns></returns> protected virtual void OnSetArrayItem(int index, JsonUnit unit) { throw new Exception($"{this.UnitType.ToString()}类型尚未支持设置索引对象"); }
/// <summary> /// 获取对象 /// </summary> /// <param name="json"></param> /// <returns></returns> public static JsonUnit ParseJson(string json) { // 初始化操作对象为空 JsonUnit res = null; JsonUnit jup = null; // 初始化字符串 string name = null; string value = null; StringBuilder sb = new StringBuilder(); // 初始化字符串和转义标志 bool isString = false; bool isEscape = false; // unicode支持 bool isUnicode = false; int uLen = 0; int uCode = 0; // 初始化操作类型为空操作 int pt = Parse_Null; // 行列计数器 int line = 1; int col = 0; //try { //遍历字符串进行解析 for (int i = 0; i < json.Length; i++) { col++; char chr = json[i]; switch (chr) { case '{': #region [=====处理左大括号=====] if (isString) { // 此字符不支持转义及Unicode if (isEscape) { throw new Exception($"规则外的\"{chr}\"操作符"); } if (isUnicode) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 当处于字符串模式时,直接添加到字符串生成器 sb.Append(chr); } else { // 判断解析类型,必须为空 if (pt == Parse_Null) { // 当处于字符串模式时,则为添加一个对象 if (jup == null) { // 无操作对象时,为顶层操作对象,不允许有名称和值 if (!(name.IsNull() || value.IsNull())) { throw new Exception($"规则外的\"{chr}\"操作符"); } res = new JsonObject(); jup = res; } else { throw new Exception($"规则外的\"{chr}\"操作符"); } } else if (pt == Parse_Value) { // 父对象不允许为空 if (jup == null) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 设置子对象 if (jup.UnitType == UnitType.Object) { if (name.IsNoneOrNull()) { throw new Exception($"语法错误:名称不允许未空"); } jup = jup.Object(name); } else if (jup.UnitType == UnitType.Array) { if (!name.IsNoneOrNull()) { throw new Exception($"语法错误:无效名称"); } jup = jup.Object(jup.Count); } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } // 清理缓存 name = null; } else { throw new Exception($"规则外的\"{chr}\"操作符"); } // 解析类型设置为值 pt = Parse_Name; } break; #endregion case '}': #region [=====处理右大括号=====] if (isString) { // 此字符不支持转义及Unicode if (isEscape) { throw new Exception($"规则外的\"{chr}\"操作符"); } if (isUnicode) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 当处于字符串模式时,直接添加到字符串生成器 sb.Append(chr); } else { // 特殊处理,如果当前为值解析,同时值为数值或null,则进行值设置操作 if (pt == Parse_Value) { // 父对象不允许为空 if (jup == null) { throw new Exception($"规则外的\"{chr}\"操作符"); } if (name.IsNoneOrNull()) { throw new Exception($"规则外的\"{chr}\"操作符"); } value = sb.ToString(); if (value == "null" || value == "Null" || value == "NULL") { // 添加NULL值 jup.String(name).Value = null; } else if (value == "true" || value == "True" || value == "TRUE") { // 添加布尔值 jup.Bool(name).Value = true; } else if (value == "false" || value == "False" || value == "FALSE") { // 添加布尔值 jup.Bool(name).Value = false; } else if (value.IsDouble()) { // 添加数值 jup.Number(name).Value = value.ToDouble(); } else { throw new Exception($"规则外的\"{chr}\"操作符"); } // 清理缓存 sb.Clear(); name = null; value = null; } else if (pt == Parse_Done_Value) { // 添加字符串值 if (name.IsNoneOrNull()) { throw new Exception($"语法错误:缺少名称"); } jup.String(name).Value = value; // 清理缓存 sb.Clear(); name = null; value = null; } else if ((pt & Parse_Done) == Parse_Done) { // 完成状态时继续 } else { throw new Exception($"规则外的\"{chr}\"操作符"); } // 当前必须要有操作对象 if (jup == null) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 返回到上层对象 jup = jup.Parent; // 解析类型设置为子对象操作完成 pt = Parse_Done_Object; } break; #endregion case '[': #region [=====处理左中括号=====] if (isString) { // 此字符不支持转义及Unicode if (isEscape) { throw new Exception($"规则外的\"{chr}\"操作符"); } if (isUnicode) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 当处于字符串模式时,直接添加到字符串生成器 sb.Append(chr); } else { // 判断解析类型,必须为空 if (pt == Parse_Null) { // 当处于字符串模式时,则为添加一个对象 if (jup == null) { // 无操作对象时,为顶层操作对象,不允许有名称和值 if (!(name.IsNull() || value.IsNull())) { throw new Exception($"规则外的\"{chr}\"操作符"); } res = new JsonArray(); jup = res; } else { throw new Exception($"规则外的\"{chr}\"操作符"); } } else if (pt == Parse_Value) { // 父对象不允许为空 if (jup == null) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 设置子对象 if (jup.UnitType == UnitType.Object) { if (name.IsNoneOrNull()) { throw new Exception($"语法错误:名称不允许未空"); } jup = jup.Array(name); } else if (jup.UnitType == UnitType.Array) { if (!name.IsNoneOrNull()) { throw new Exception($"语法错误:无效名称"); } jup = jup.Array(jup.Count); } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } // 清理缓存 name = null; } else { throw new Exception($"规则外的\"{chr}\"操作符"); } // 解析类型设置为值 pt = Parse_Value; } break; #endregion case ']': #region [=====处理右中括号=====] if (isString) { // 此字符不支持转义及Unicode if (isEscape) { throw new Exception($"规则外的\"{chr}\"操作符"); } if (isUnicode) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 当处于字符串模式时,直接添加到字符串生成器 sb.Append(chr); } else { // 特殊处理,如果当前为值解析,同时值为数值或null,则进行值设置操作 if (pt == Parse_Value) { // 父对象不允许为空 if (jup == null) { throw new Exception($"规则外的\"{chr}\"操作符"); } if (!name.IsNoneOrNull()) { throw new Exception($"语法错误:无效名称"); } value = sb.ToString(); if (value == "null" || value == "Null" || value == "NULL") { // 添加NULL值 jup.String(jup.Count).Value = null; } else if (value == "true" || value == "True" || value == "TRUE") { // 添加布尔值 jup.Bool(jup.Count).Value = true; } else if (value == "false" || value == "False" || value == "FALSE") { // 添加布尔值 jup.Bool(jup.Count).Value = false; } else if (value.IsDouble()) { // 添加数值 jup.Number(jup.Count).Value = value.ToDouble(); } else { throw new Exception($"规则外的\"{chr}\"操作符"); } // 清理缓存 sb.Clear(); name = null; value = null; } else if (pt == Parse_Done_Value) { // 添加字符串值 if (!name.IsNoneOrNull()) { throw new Exception($"语法错误:无效名称"); } jup.String(jup.Count).Value = value; // 清理缓存 sb.Clear(); name = null; value = null; } else if ((pt & Parse_Done) == Parse_Done) { // 完成状态时继续 } else { throw new Exception($"规则外的\"{chr}\"操作符"); } // 当前必须要有操作对象 if (jup == null) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 返回到上层对象 jup = jup.Parent; // 解析类型设置为子对象操作完成 pt = Parse_Done_Array; } break; #endregion case '\\': #region [=====处理转义符=====] if (isString) { // 此字符不支持Unicode if (isUnicode) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 当处于字符串模式时,操作转义 if (isEscape) { // 当处于转义模式,则直接添加字符并退出转义 sb.Append(chr); isEscape = false; } else { // 当未处于转义模式,则进入转义模式 isEscape = true; } } else { throw new Exception($"规则外的\"{chr}\"操作符"); } break; #endregion case '"': #region [=====处理双引号=====] if (isString) { // 此字符不支持Unicode if (isUnicode) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 当处于字符串模式时,操作转义 if (isEscape) { // 当处于转义模式,则直接添加字符并退出转义 sb.Append(chr); isEscape = false; } else { // 当未处于转义模式,则表示字符串结束 if (pt == Parse_Name) { // 名称模式,则设置名称 name = sb.ToString(); sb.Clear(); pt = Parse_Done_Name; } else if (pt == Parse_Value) { // 值模式,则设置值 value = sb.ToString(); sb.Clear(); pt = Parse_Done_Value; } else { throw new Exception($"规则外的\"{chr}\"操作符"); } // 退出字符串模式 isString = false; } } else { // 当未处于字符串模式时,则进入字符串模式 if (pt == Parse_Name) { if (!name.IsNull()) { throw new Exception($"规则外的\"{chr}\"操作符"); } isString = true; } else if (pt == Parse_Value) { if (!value.IsNull()) { throw new Exception($"规则外的\"{chr}\"操作符"); } isString = true; } else { throw new Exception($"规则外的\"{chr}\"操作符"); } } break; #endregion case ':': #region [=====处理冒号=====] if (isString) { // 此字符不支持转义及Unicode if (isEscape) { throw new Exception($"规则外的\"{chr}\"操作符"); } if (isUnicode) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 当处于字符串模式时,直接添加到字符串生成器 sb.Append(chr); } else { // 特殊处理,如果当前为名称解析时,完成名称解析 if (pt == Parse_Name) { // 当名称模式时,可作为隐藏结束符使用 name = sb.ToString(); if (name.IsNoneOrNull()) { throw new Exception($"语法错误,名称不允许未空"); } sb.Clear(); // 设置为值模式 pt = Parse_Value; } else if (pt == Parse_Done_Name) { // 设置为值模式 pt = Parse_Value; } else { throw new Exception($"规则外的\"{chr}\"操作符"); } } break; #endregion case ',': #region [=====处理逗号=====] if (isString) { // 此字符不支持转义及Unicode if (isEscape) { throw new Exception($"规则外的\"{chr}\"操作符"); } if (isUnicode) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 当处于字符串模式时,直接添加到字符串生成器 sb.Append(chr); } else { // 父对象不允许为空 if (jup == null) { throw new Exception($"规则外的\"{chr}\"操作符"); } // 特殊处理,如果当前为值解析时,完成数值解析 if (pt == Parse_Value || pt == Parse_Done_Value) { // 当为内容时,进行内容添加 if (pt == Parse_Value) { // 当为值模式时,可作为隐藏结束符使用 value = sb.ToString(); if (value == "null" || value == "Null" || value == "NULL") { // 添加字符串值 if (jup.UnitType == UnitType.Object) { jup.String(name).Value = null; } else if (jup.UnitType == UnitType.Array) { jup.String(jup.Count).Value = null; } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } } else if (value == "true" || value == "True" || value == "TRUE") { // 添加布尔值 if (jup.UnitType == UnitType.Object) { jup.Bool(name).Value = true; } else if (jup.UnitType == UnitType.Array) { jup.Bool(jup.Count).Value = true; } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } } else if (value == "false" || value == "False" || value == "FALSE") { // 添加布尔值 if (jup.UnitType == UnitType.Object) { jup.Bool(name).Value = false; } else if (jup.UnitType == UnitType.Array) { jup.Bool(jup.Count).Value = false; } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } } else if (value.IsDouble()) { // 添加数值 double dbl = value.ToDouble(); if (jup.UnitType == UnitType.Object) { jup.Number(name).Value = dbl; } else if (jup.UnitType == UnitType.Array) { jup.Number(jup.Count).Value = dbl; } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } } else { throw new Exception($"语法错误:字符串必须使用双引号定义"); } // 清理缓存 sb.Clear(); name = null; value = null; } else { // 添加字符串值 if (jup.UnitType == UnitType.Object) { jup.String(name).Value = value; } else if (jup.UnitType == UnitType.Array) { jup.String(jup.Count).Value = value; } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } // 清理缓存 sb.Clear(); name = null; value = null; } } else if (pt == Parse_Done_Object || pt == Parse_Done_Array) { // 当为对象或数组时,则进入下一个对象的操作 } else { throw new Exception($"规则外的\"{chr}\"操作符"); } // 判断父对象类型 if (jup.UnitType == UnitType.Object) { // 当父对象是对象时,设置子对象,进入名称模式 pt = Parse_Name; } else if (jup.UnitType == UnitType.Array) { // 当父对象是对象时,进入值模式 pt = Parse_Value; } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } } break; #endregion case ' ': #region [=====处理空格=====] if (isString) { // 此字符不支持转义 if (isEscape) { throw new Exception($"规则外的\"{chr}\"字符"); } // 当处于字符串模式时,直接添加到字符串生成器 sb.Append(chr); } else { if (pt == Parse_Name) { // 当名称模式时,可作为隐藏结束符使用 name = sb.ToString(); if (name.IsNoneOrNull()) { throw new Exception($"语法错误:名称不允许未空"); } sb.Clear(); pt = Parse_Done_Name; } else if (pt == Parse_Value) { // 当名称模式时,可作为隐藏结束符使用 value = sb.ToString(); if (value == "null" || value == "Null" || value == "NULL") { // 添加字符串值 if (jup.UnitType == UnitType.Object) { if (name.IsNoneOrNull()) { throw new Exception($"语法错误:名称不允许未空"); } jup.String(name).Value = null; } else if (jup.UnitType == UnitType.Array) { if (!name.IsNoneOrNull()) { throw new Exception($"语法错误:无效名称"); } jup.String(jup.Count).Value = null; } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } } else if (value == "true" || value == "True" || value == "TRUE") { // 添加布尔值 if (jup.UnitType == UnitType.Object) { jup.Bool(name).Value = true; } else if (jup.UnitType == UnitType.Array) { jup.Bool(jup.Count).Value = true; } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } } else if (value == "false" || value == "False" || value == "FALSE") { // 添加布尔值 if (jup.UnitType == UnitType.Object) { jup.Bool(name).Value = false; } else if (jup.UnitType == UnitType.Array) { jup.Bool(jup.Count).Value = false; } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } } else if (value.IsDouble()) { // 添加数值 double dbl = value.ToDouble(); if (jup.UnitType == UnitType.Object) { if (name.IsNoneOrNull()) { throw new Exception($"语法错误:名称不允许未空"); } jup.Number(name).Value = dbl; } else if (jup.UnitType == UnitType.Array) { if (!name.IsNoneOrNull()) { throw new Exception($"语法错误:无效名称"); } jup.Number(jup.Count).Value = dbl; } else { throw new Exception($"数据类型\"{jup.UnitType.ToString()}\"不支持设置子元素"); } } else { throw new Exception($"语法错误:字符串必须使用双引号定义"); } sb.Clear(); pt = Parse_Done_Value; } } break; #endregion case '\r': break; //忽略回车符 case '\n': #region [=====处理换行=====] if (isString) { // 不支持字符串中换行 throw new Exception($"规则外的换行符"); } line++; col = 0; break; #endregion case 'u': #region [=====处理u字符=====] if (isString) { // 不支持的转义字符 if (isUnicode) { throw new Exception($"规则外的\"{chr}\"字符"); } // 字符串中处理 if (isEscape) { // 当为转义时,进入unicode模式 isUnicode = true; isEscape = false; } else { // 将字符添加到字符串生成器 sb.Append(chr); } } else { // 将字符添加到字符串生成器 sb.Append(chr); } break; #endregion case 'n': #region [=====处理n字符=====] if (isString) { // 不支持的转义字符 if (isUnicode) { throw new Exception($"规则外的\"{chr}\"字符"); } // 字符串中处理 if (isEscape) { // 当为转义时,添加换行符 sb.Append('\n'); isEscape = false; } else { // 将字符添加到字符串生成器 sb.Append(chr); } } else { // 将字符添加到字符串生成器 sb.Append(chr); } break; #endregion case 'r': #region [=====处理r字符=====] if (isString) { // 不支持的转义字符 if (isUnicode) { throw new Exception($"规则外的\"{chr}\"字符"); } // 字符串中处理 if (isEscape) { // 当为转义时,添加回车符 sb.Append('\r'); } else { // 将字符添加到字符串生成器 sb.Append(chr); isEscape = false; } } else { // 将字符添加到字符串生成器 sb.Append(chr); } break; #endregion case '/': #region [=====处理r字符=====] if (isString) { // 不支持的转义字符 if (isUnicode) { throw new Exception($"规则外的\"{chr}\"字符"); } // 字符串中处理 if (isEscape) { // 当为转义时,添加回车符 sb.Append(chr); isEscape = false; } else { // 将字符添加到字符串生成器 sb.Append(chr); } } else { // 将字符添加到字符串生成器 sb.Append(chr); } break; #endregion default: if (isString) { // 字符串处理 if (isEscape) { switch (chr) { case 'n': sb.Append('\n'); break; case 'r': sb.Append('\r'); break; case '/': sb.Append('/'); break; case 'b': sb.Append('\b'); break; case 'f': sb.Append('\f'); break; case 't': sb.Append('\t'); break; default: throw new Exception($"规则外的\"{chr}\"字符"); } isEscape = false; } else if (isUnicode) { uLen++; uCode += int.Parse(chr.ToString(), System.Globalization.NumberStyles.HexNumber) * (int)Math.Pow(16, 4 - uLen); if (uLen == 4) { char uc = (char)uCode; // 将字符添加到字符串生成器 sb.Append(uc); isUnicode = false; uLen = 0; uCode = 0; } } else { // 将字符添加到字符串生成器 sb.Append(chr); } } else { // 所有完成状态之后不允许尾随字符 if ((pt & Parse_Done) == Parse_Done) { throw new Exception($"规则外的\"{chr}\"字符"); } // 将字符添加到字符串生成器 sb.Append(chr); } break; } } //} catch (Exception ex) { // throw new Exception($"行 {line} 字符 {col} 解析发生异常", ex); //} if (jup != null) { throw new Exception($"语法错误:Json代码不完整"); } return(res); }
/// <summary> /// 将Json对象覆盖到标准对象 /// </summary> /// <param name="unit"></param> /// <param name="tp"></param> /// <returns></returns> public static object GetObject(JsonUnit unit, Type tp) { object obj; if (unit == null) { return(null); } //var tp = obj.GetType(); switch (tp.FullName) { case "System.String": // 覆盖字符串 obj = unit.GetString(); break; case "System.Int32": // 覆盖整型 obj = (int)unit.GetNumber(); break; case "System.Int64": // 覆盖长整型 obj = (long)unit.GetNumber(); break; case "System.Single": // 覆盖单精度浮点类型 obj = (float)unit.GetNumber(); break; case "System.Double": // 覆盖双精度浮点类型 obj = unit.GetNumber(); break; case "System.Boolean": // 覆盖布尔类型 obj = unit.GetBoolean(); break; default: if (tp.Name == "List`1") { // 覆盖列表 var ptct = tp.GetConstructor(System.Type.EmptyTypes); obj = ptct.Invoke(null); var objAdd = tp.GetMethod("Add"); //List<object> list = (List<object>)obj; // 获取列表关联类型 var gas = tp.GetGenericArguments(); Type ga = null; if (gas.Length > 0) { ga = gas[0]; } // 添加列表单元 for (int i = 0; i < unit.Count; i++) { objAdd.Invoke(obj, new object[] { GetObject(unit[i], ga) }); } } else { // 覆盖对象 var ptct = tp.GetConstructor(System.Type.EmptyTypes); obj = ptct.Invoke(null); var pros = tp.GetProperties(); // 遍历属性 foreach (var pro in pros) { var pto = GetObject(unit[pro.Name], pro.PropertyType); pro.SetValue(obj, pto, null); } } break; } return(obj); }