IT民工——发一个万能的JSON解析器吧!

针对Newtonsoft解析Unicode问题及类同步难题,设计了一款自定义的JSON解析模型,支持复杂结构解析,包括值、对象与集合。通过示例展示了如何使用此解析器获取JSON中的特定值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言
之前一直在用Newtonsoft的json解析,但是实在烂的可以!!!

首先,对于unicode无法解析,竟然跟我删除了\u,返回一堆码(\u6211-> 6211),我都火了!
还有,如果对方json一变,我这边写的class没有同步,就会报错!

最后我只能靠自己,写一个json通用模型去解析了。

概念介绍
还是先简单说说Json的一些例子吧。注意,以下概念是我自己定义的,可以参考.net里面的TYPE的模型设计
如果有争议,欢迎提出来探讨!
1.最简单:
{"total":0}
total就是值,值是数值,等于0
2. 复杂点
{"total":0,"data":{"377149574" : 1}}
total是值,data是对象,这个对象包含了"377149574"这个值,等于1
3. 最复杂
{"total":0,"data":{"377149574":[{"cid":"377149574"}]}}
total是值,data是对象,377149574是数组,这个数组包含了一些列的对象,例如{"cid":"377149574"}这个对象。

有了以上的概念,就可以设计出通用的json模型了。

源代码
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Text;

namespace Pixysoft.Json
{
    
public class CommonJsonModelAnalyzer
    {
        
protected string _GetKey(string rawjson)
        {
            
if (string.IsNullOrEmpty(rawjson))
                
return rawjson;

            rawjson 
= rawjson.Trim();

            
string[] jsons = rawjson.Split(new char[] { ':' });

            
if (jsons.Length < 2)
                
return rawjson;

            
return jsons[0].Replace("\"""").Trim();
        }

        
protected string _GetValue(string rawjson)
        {
            
if (string.IsNullOrEmpty(rawjson))
                
return rawjson;

            rawjson 
= rawjson.Trim();

            
string[] jsons = rawjson.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);

            
if (jsons.Length < 2)
                
return rawjson;

            StringBuilder builder 
= new StringBuilder();

            
for (int i = 1; i < jsons.Length; i++)
            {
                builder.Append(jsons[i]);

                builder.Append(
":");
            }

            
if (builder.Length > 0)
                builder.Remove(builder.Length 
- 11);

            
string value = builder.ToString();

            
if (value.StartsWith("\""))
                value = value.Substring(1);

            
if (value.EndsWith("\""))
                value = value.Substring(0, value.Length - 1);

            
return value;
        }

        
protected List<string> _GetCollection(string rawjson)
        {
            
//[{},{}]

            List
<string> list = new List<string>();

            
if (string.IsNullOrEmpty(rawjson))
                
return list;

            rawjson 
= rawjson.Trim();

            StringBuilder builder 
= new StringBuilder();

            
int nestlevel = -1;

            
int mnestlevel = -1;

            
for (int i = 0; i < rawjson.Length; i++)
            {
                
if (i == 0)
                    
continue;
                
else if (i == rawjson.Length - 1)
                    
continue;

                
char jsonchar = rawjson[i];

                
if (jsonchar == '{')
                {
                    nestlevel
++;
                }

                
if (jsonchar == '}')
                {
                    nestlevel
--;
                }

                
if (jsonchar == '[')
                {
                    mnestlevel
++;
                }

                
if (jsonchar == ']')
                {
                    mnestlevel
--;
                }

                
if (jsonchar == ',' && nestlevel == -1 && mnestlevel == -1)
                {
                    list.Add(builder.ToString());

                    builder 
= new StringBuilder();
                }
                
else
                {
                    builder.Append(jsonchar);
                }
            }

            
if (builder.Length > 0)
                list.Add(builder.ToString());

            
return list;
        }
    }
}

ContractedBlock.gifExpandedBlockStart.gifCode
using System;
using System.Collections.Generic;
using System.Text;

namespace Pixysoft.Json
{
    
public class CommonJsonModel : CommonJsonModelAnalyzer
    {
        
private string rawjson;

        
private bool isValue = false;

        
private bool isModel = false;

        
private bool isCollection = false;

        
internal CommonJsonModel(string rawjson)
        {
            
this.rawjson = rawjson;

            
if (string.IsNullOrEmpty(rawjson))
                
throw new Exception("missing rawjson");

            rawjson 
= rawjson.Trim();

            
if (rawjson.StartsWith("{"))
            {
                isModel 
= true;
            }
            
else if (rawjson.StartsWith("["))
            {
                isCollection 
= true;
            }
            
else
            {
                isValue 
= true;
            }
        }

        
public string Rawjson
        {
            
get { return rawjson; }
        }

        
public bool IsValue()
        {
            
return isValue;
        }
        
public bool IsValue(string key)
        {
            
if (!isModel)
                
return false;

            
if (string.IsNullOrEmpty(key))
                
return false;

            
foreach (string subjson in base._GetCollection(this.rawjson))
            {
                CommonJsonModel model 
= new CommonJsonModel(subjson);

                
if (!model.IsValue())
                    
continue;

                
if (model.Key == key)
                {
                    CommonJsonModel submodel 
= new CommonJsonModel(model.Value);

                    
return submodel.IsValue();
                }
            }

            
return false;
        }
        
public bool IsModel()
        {
            
return isModel;
        }
        
public bool IsModel(string key)
        {
            
if (!isModel)
                
return false;

            
if (string.IsNullOrEmpty(key))
                
return false;

            
foreach (string subjson in base._GetCollection(this.rawjson))
            {
                CommonJsonModel model 
= new CommonJsonModel(subjson);

                
if (!model.IsValue())
                    
continue;

                
if (model.Key == key)
                {
                    CommonJsonModel submodel 
= new CommonJsonModel(model.Value);

                    
return submodel.IsModel();
                }
            }

            
return false;
        }
        
public bool IsCollection()
        {
            
return isCollection;
        }
        
public bool IsCollection(string key)
        {
            
if (!isModel)
                
return false;

            
if (string.IsNullOrEmpty(key))
                
return false;

            
foreach (string subjson in base._GetCollection(this.rawjson))
            {
                CommonJsonModel model 
= new CommonJsonModel(subjson);

                
if (!model.IsValue())
                    
continue;

                
if (model.Key == key)
                {
                    CommonJsonModel submodel 
= new CommonJsonModel(model.Value);

                    
return submodel.IsCollection();
                }
            }

            
return false;
        }


        
/// <summary>
        
/// 当模型是对象,返回拥有的key
        
/// </summary>
        
/// <returns></returns>
        public List<string> GetKeys()
        {
            
if (!isModel)
                
return null;

            List
<string> list = new List<string>();

            
foreach (string subjson in base._GetCollection(this.rawjson))
            {
                
string key = new CommonJsonModel(subjson).Key;

                
if (!string.IsNullOrEmpty(key))
                    list.Add(key);
            }

            
return list;
        }

        
/// <summary>
        
/// 当模型是对象,key对应是值,则返回key对应的值
        
/// </summary>
        
/// <param name="key"></param>
        
/// <returns></returns>
        public string GetValue(string key)
        {
            
if (!isModel)
                
return null;

            
if (string.IsNullOrEmpty(key))
                
return null;

            
foreach (string subjson in base._GetCollection(this.rawjson))
            {
                CommonJsonModel model 
= new CommonJsonModel(subjson);

                
if (!model.IsValue())
                    
continue;

                
if (model.Key == key)
                    
return model.Value;
            }

            
return null;
        }

        
/// <summary>
        
/// 模型是对象,key对应是对象,返回key对应的对象
        
/// </summary>
        
/// <param name="key"></param>
        
/// <returns></returns>
        public CommonJsonModel GetModel(string key)
        {
            
if (!isModel)
                
return null;

            
if (string.IsNullOrEmpty(key))
                
return null;

            
foreach (string subjson in base._GetCollection(this.rawjson))
            {
                CommonJsonModel model 
= new CommonJsonModel(subjson);

                
if (!model.IsValue())
                    
continue;

                
if (model.Key == key)
                {
                    CommonJsonModel submodel 
= new CommonJsonModel(model.Value);

                    
if (!submodel.IsModel())
                        
return null;
                    
else
                        
return submodel;
                }
            }

            
return null;
        }

        
/// <summary>
        
/// 模型是对象,key对应是集合,返回集合
        
/// </summary>
        
/// <param name="key"></param>
        
/// <returns></returns>
        public CommonJsonModel GetCollection(string key)
        {
            
if (!isModel)
                
return null;

            
if (string.IsNullOrEmpty(key))
                
return null;

            
foreach (string subjson in base._GetCollection(this.rawjson))
            {
                CommonJsonModel model 
= new CommonJsonModel(subjson);

                
if (!model.IsValue())
                    
continue;

                
if (model.Key == key)
                {
                    CommonJsonModel submodel 
= new CommonJsonModel(model.Value);

                    
if (!submodel.IsCollection())
                        
return null;
                    
else
                        
return submodel;
                }
            }

            
return null;
        }

        
/// <summary>
        
/// 模型是集合,返回自身
        
/// </summary>
        
/// <returns></returns>
        public List<CommonJsonModel> GetCollection()
        {
            List
<CommonJsonModel> list = new List<CommonJsonModel>();

            
if (IsValue())
                
return list;

            
foreach (string subjson in base._GetCollection(rawjson))
            {
                list.Add(
new CommonJsonModel(subjson));
            }

            
return list;
        }




        
/// <summary>
        
/// 当模型是值对象,返回key
        
/// </summary>
        private string Key
        {
            
get
            {
                
if (IsValue())
                    
return base._GetKey(rawjson);

                
return null;
            }
        }
        
/// <summary>
        
/// 当模型是值对象,返回value
        
/// </summary>
        private string Value
        {
            
get
            {
                
if (!IsValue())
                    
return null;

                
return base._GetValue(rawjson);
            }
        }
    }
}
使用方法
        public CommonJsonModel DeSerialize(string  json)
        {
            
return new
 CommonJsonModel(json);
        }

超级简单,只要new一个通用对象,把json字符串放进去就行了。

针对上文的3个例子,我给出3种使用方法:
{"total":0}
CommonJsonModel model =  DeSerialize(json);

model.GetValue(
"total"// return 0

{"total":0,"data":{"377149574" : 1}}
CommonJsonModel model =  DeSerialize(json);

model.GetModel(
"data").GetValue("377149574"//return 1

{"total":0,"data":{"377149574":[{"cid":"377149574"}]}}
CommonJsonModel model =  DeSerialize(json);
model.GetModel("data").GetCollection(
"377149574").GetCollection()[0].GetValue("cid"//return 377149574

这个有点点复杂,
1. 首先在data对象里面,377149574代表了一个集合,所以要用model.GetModel("data").GetCollection("377149574")把这个集合取出来。
2. 其次这个集合里面包含了很多对象,因此用GetColllection()把这些对象取出来
3. 在这些对象List里面取第一个[0],表示取了":{"cid":"377149574"}这个对象,然后再用GetValue("cid")把对象的值取出来。

后记
可能我的思路复杂了点,希望给点建议!谢谢!

IT民工上

2009/8/17


转载于:https://www.cnblogs.com/zc22/archive/2009/08/17/1547795.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值