如何反序列化 JSON 数据?

Posted

技术标签:

【中文标题】如何反序列化 JSON 数据?【英文标题】:How to Deserialize JSON data? 【发布时间】:2013-08-17 00:53:16 【问题描述】:

我是处理 JSON 数据的新手。

我正在从 Web 服务读取数据。返回的查询数据如下:

[["B02001_001E","NAME","state"],
 ["4712651","Alabama","01"],
 ["691189","Alaska","02"],
 ["6246816","Arizona","04"],
 ["18511620","Florida","12"],
 ["9468815","Georgia","13"],
 ["1333591","Hawaii","15"],
 ["1526797","Idaho","16"],
 ["3762322","Puerto Rico","72"]]

有没有一种方法可以反序列化这些数据,从而在我没有先定义对象是什么样的情况下生成基础对象?在上面的例子中,对象由第一行定义:

           ["B02001_001E","NAME","state"],

通常,Web 服务将返回格式为二维 JSON 数组的查询数据,其中第一行提供列名,后续行提供数据值。

【问题讨论】:

【参考方案1】:

你可以很容易地反序列化它。 C# 中的数据结构只是List<string[]>,所以你可以这样做;

  List<string[]> data = JsonConvert.DeserializeObject<List<string[]>>(jsonString);

以上代码假设您使用的是 json.NET。

编辑:注意 json 在技术上是一个字符串数组。我更喜欢在我自己的声明中使用List&lt;string[]&gt;,因为它更直观。它不会对 json.NET 造成任何问题,如果您希望它是字符串数组的数组,那么您需要将类型更改为(我认为)string[][],但是锯齿状数组和二维数组有一些有趣的小问题在我不太了解的 C# 中,所以我只是不费心在这里处理它。

【讨论】:

【参考方案2】:

如果你使用 .Net 4.5,你也可以使用标准的 .Net json 序列化器:

using System.Runtime.Serialization.Json;
...    
Stream jsonSource = ...; // serializer will read data stream
var s = new DataContractJsonSerializer(typeof(string[][]));
var j = (string[][])s.ReadObject(jsonSource);

在 .Net 4.5 及更早版本中,您可以使用 javascriptSerializer 类:

using System.Web.Script.Serialization;
...
JavaScriptSerializer serializer = new JavaScriptSerializer();
string[][] list = serializer.Deserialize<string[][]>(json);

【讨论】:

【参考方案3】:

第 1 步:访问 json.org 以查找 JSON 库,以了解您用于调用此 Web 服务的任何技术。下载并链接到该库。

第 2 步:假设您使用的是 Java。你会像这样使用 JSONArray:

JSONArray myArray=new JSONArray(queryResponse);
for (int i=0;i<myArray.length;i++)
    JSONArray myInteriorArray=myArray.getJSONArray(i);
    if (i==0) 
        //this is the first one and is special because it holds the name of the query.
    else
        //do your stuff
        String stateCode=myInteriorArray.getString(0);
        String stateName=myInteriorArray.getString(1);
    

【讨论】:

【参考方案4】:

您可以编写自己的 JSON 解析器,并根据您的要求使其更通用。这是一个很好地服务于我的目的,希望对你也有帮助。

class JsonParsor

    public static DataTable JsonParse(String rawJson)
    
        DataTable dataTable = new DataTable();
        Dictionary<string, string> outdict = new Dictionary<string, string>();
        StringBuilder keybufferbuilder = new StringBuilder();
        StringBuilder valuebufferbuilder = new StringBuilder();
        StringReader bufferreader = new StringReader(rawJson);
        int s = 0;
        bool reading = false;
        bool inside_string = false;
        bool reading_value = false;
        bool reading_number = false;
        while (s >= 0)
        
            s = bufferreader.Read();
            //open JSON
            if (!reading)
            
                if ((char)s == '' && !inside_string && !reading)
                
                    reading = true;
                    continue;
                
                if ((char)s == '' && !inside_string && !reading)
                    break;
                if ((char)s == ']' && !inside_string && !reading)
                    continue;
                if ((char)s == ',')
                    continue;
            
            else
            
                if (reading_value)
                
                    if (!inside_string && (char)s >= '0' && (char)s <= '9')
                    
                        reading_number = true;
                        valuebufferbuilder.Append((char)s);
                        continue;
                    
                
                //if we find a quote and we are not yet inside a string, advance and get inside
                if (!inside_string)
                
                    if ((char)s == '\"' && !inside_string)
                        inside_string = true;
                    if ((char)s == '[' && !inside_string)
                    
                        keybufferbuilder.Length = 0;
                        valuebufferbuilder.Length = 0;
                                reading = false;
                                inside_string = false;
                                reading_value = false;
                    
                    if ((char)s == ',' && !inside_string && reading_number)
                    
                        if (!dataTable.Columns.Contains(keybufferbuilder.ToString()))
                            dataTable.Columns.Add(keybufferbuilder.ToString(), typeof(string));
                        if (!outdict.ContainsKey(keybufferbuilder.ToString()))
                            outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString());
                        keybufferbuilder.Length = 0;
                        valuebufferbuilder.Length = 0;
                        reading_value = false;
                        reading_number = false;
                    
                    continue;
                

                //if we reach end of the string
                if (inside_string)
                
                    if ((char)s == '\"')
                    
                        inside_string = false;
                        s = bufferreader.Read();
                        if ((char)s == ':')
                        
                            reading_value = true;
                            continue;
                        
                        if (reading_value && (char)s == ',')
                        
                            //put the key-value pair into dictionary
                            if(!dataTable.Columns.Contains(keybufferbuilder.ToString()))
                                dataTable.Columns.Add(keybufferbuilder.ToString(),typeof(string));
                            if (!outdict.ContainsKey(keybufferbuilder.ToString()))
                            outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString());
                            keybufferbuilder.Length = 0;
                            valuebufferbuilder.Length = 0;
                            reading_value = false;
                        
                        if (reading_value && (char)s == '')
                        
                            if (!dataTable.Columns.Contains(keybufferbuilder.ToString()))
                                dataTable.Columns.Add(keybufferbuilder.ToString(), typeof(string));
                            if (!outdict.ContainsKey(keybufferbuilder.ToString()))
                                outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString());
                            ICollection key = outdict.Keys;
                            DataRow newrow = dataTable.NewRow();
                            foreach (string k_loopVariable in key)
                            
                                CommonModule.LogTheMessage(outdict[k_loopVariable],"","","");
                                newrow[k_loopVariable] = outdict[k_loopVariable];
                            
                            dataTable.Rows.Add(newrow);
                            CommonModule.LogTheMessage(dataTable.Rows.Count.ToString(), "", "row_count", "");
                            outdict.Clear();
                            keybufferbuilder.Length=0;
                            valuebufferbuilder.Length=0;
                            reading_value = false;
                            reading = false;
                            continue;
                        
                    
                    else
                    
                        if (reading_value)
                        
                            valuebufferbuilder.Append((char)s);
                            continue;
                        
                        else
                        
                            keybufferbuilder.Append((char)s);
                            continue;
                        
                    
                
                else
                
                    switch ((char)s)
                    
                        case ':':
                            reading_value = true;
                            break;
                        default:
                            if (reading_value)
                            
                                valuebufferbuilder.Append((char)s);
                            
                            else
                            
                                keybufferbuilder.Append((char)s);
                            
                            break;
                    
                
            
        

        return dataTable;
    

【讨论】:

以上是关于如何反序列化 JSON 数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JSON 反序列化期间将引用转换为实例

如何反序列化 json 数组?

[C#]如何使用Newton.Json从流中反序列化json数据

反序列化复杂的 JSON 数据

如何在 Jackson 中记录 JSON 反序列化

JSON序列化