解析具有不同类型值的json(Newtonsoft.Json) [英] Parse json with different types value (Newtonsoft.Json)

查看:425
本文介绍了解析具有不同类型值的json(Newtonsoft.Json)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

帮我用Newtonsoft.Json解析json.

  {
    "_id": 160,
    "location": {
        "type": "Point",
        "coordinates": [43.59043144045182, 39.72119003534317]
    },  
},
{
    "_id": 161, 
    "location": {
        "type": "LineString",
        "coordinates": [
            [43.58780105200211, 39.719191789627075],
            [43.58817794899264, 39.719465374946594]
        ]
    },  
},
{
    "_id": 152, 
        "location": {
            "type": "Polygon",
            "coordinates": [
                [43.590524759627954, 39.71930980682373],
                [43.590474249766544, 39.71926689147949],
                [43.59043151061995, 39.71934735774994],
                [43.59073456936772, 39.71958339214325],
                [43.59076565222992, 39.71949219703674]
            ]
        },
}

coordinates的类型为List<double>List<List<double>>,具体取决于键type(多边形,线串,点).

Key coordinates has type List<double> or List<List<double>> depending on the key type (Polygon, LineString, Point).

推荐答案

您可以使用自定义的JsonConverter解决此问题.转换器可以加载每种形状的数据,查看type字段,然后相应地填充坐标数组.实际上,如果您愿意,转换器可以在此处执行双重任务,以便在我们处理数据时将数据整理为更简单的类结构.鉴于您提供的JSON,我将按照以下方式进行操作.

You can solve this problem using a custom JsonConverter. The converter can load the data for each shape, look at the type field and then populate the coordinates array accordingly. And actually, if you want, the converter can do double-duty here to flatten the data down into a simpler class structure while we're at it. Here's how I would do it, given the JSON you have presented.

首先,定义一个类来保存反序列化的形状数据.我们将反序列化为以下列表:

First, define a class to hold the deserialized shape data. We'll deserialize into a list of these:

class Shape
{
    public int Id { get; set; }
    public string Type { get; set; }
    public List<List<double>> Coordinates { get; set; }
}

接下来创建转换器类.这负责将每种形状的JSON转换为具体的Shape对象.

Next create the converter class. This is responsible for transforming the JSON for each shape into a concrete Shape object.

class ShapeConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Shape));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        Shape shape = new Shape();
        shape.Id = (int)jo["_id"];
        shape.Type = (string)jo["location"]["type"];
        JArray ja = (JArray)jo["location"]["coordinates"];
        if (shape.Type == "Point")
        {
            shape.Coordinates = new List<List<double>>();
            shape.Coordinates.Add(ja.ToObject<List<double>>());
        }
        else
        {
            shape.Coordinates = ja.ToObject<List<List<double>>>();
        }
        return shape;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Shape类中添加[JsonConverter]属性以将其绑定到ShapeConverter:

Add a [JsonConverter] attribute to the Shape class to tie it to the ShapeConverter:

[JsonConverter(typeof(ShapeConverter))]
class Shape
{
    ...
}

剩下的就是反序列化JSON了,我们可以这样做:

All that is left is to deserialize the JSON, which we can do like this:

List<Shape> shapes = JsonConvert.DeserializeObject<List<Shape>>(json);

这是一个演示以下内容的测试程序:

Here is a test program to demonstrate:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        [
            {
                ""_id"": 160,
                ""location"": {
                    ""type"": ""Point"",
                    ""coordinates"": [ 43.59043144045182, 39.72119003534317 ]
                }
            },
            {
                ""_id"": 161,
                ""location"": {
                    ""type"": ""LineString"",
                    ""coordinates"": [
                        [ 43.58780105200211, 39.719191789627075 ],
                        [ 43.58817794899264, 39.719465374946594 ]
                    ]
                }
            },
            {
                ""_id"": 152,
                ""location"": {
                    ""type"": ""Polygon"",
                    ""coordinates"": [
                        [ 43.590524759627954, 39.71930980682373 ],
                        [ 43.590474249766544, 39.71926689147949 ],
                        [ 43.59043151061995, 39.71934735774994 ],
                        [ 43.59073456936772, 39.71958339214325 ],
                        [ 43.59076565222992, 39.71949219703674 ]
                    ]
                }
            }
        ]";

        List<Shape> shapes = JsonConvert.DeserializeObject<List<Shape>>(json);

        foreach (Shape shape in shapes)
        {
            Console.WriteLine("Id: " + shape.Id);
            Console.WriteLine("Type: " + shape.Type);
            Console.WriteLine("Coordinates: ");
            foreach (List<double> point in shape.Coordinates)
            {
                Console.WriteLine("   (" + point[0] + ", " + point[1] + ")");
            }
            Console.WriteLine();
        }
    }
}

输出:

Id: 160
Type: Point
Coordinates:
   (43.5904314404518, 39.7211900353432)

Id: 161
Type: LineString
Coordinates:
   (43.5878010520021, 39.7191917896271)
   (43.5881779489926, 39.7194653749466)

Id: 152
Type: Polygon
Coordinates:
   (43.590524759628, 39.7193098068237)
   (43.5904742497665, 39.7192668914795)
   (43.59043151062, 39.7193473577499)
   (43.5907345693677, 39.7195833921433)
   (43.5907656522299, 39.7194921970367)

如果想花更多的钱,可以为每个坐标使用Point结构而不是List<double>,并且/或者可以为每种复杂形状的类型(例如,线,多边形)创建实际的类层次结构)并组成Points.如果需要,可以很容易地修改转换器以创建这些对象.我会把那部分留给你.

If you want to get more fancy, you can use a Point struct instead of a List<double> for each coordinate, and/or you can create an actual class hierarchy for each type of complex shape (e.g. Line, Polygon) and compose them of Points. It would not be difficult to modify the converter to create these objects if desired. I'll leave that part to you.

这篇关于解析具有不同类型值的json(Newtonsoft.Json)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆