解析具有不同类型值的json(Newtonsoft.Json)

Ale*_*ndr 0 c# json json.net windows-phone-7 windows-phone-8

帮我解析jsonNewtonsoft.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]
            ]
        },
}
Run Code Online (Sandbox Code Playgroud)

coordinates具有类型List<double>List<List<double>>取决于键type(多边形,线串,点)。

Bri*_*ers 6

您可以使用custom解决此问题JsonConverter。转换器可以加载每种形状的数据,查看type字段,然后相应地填充坐标数组。实际上,如果您愿意,转换器可以在此处执行双重任务,以在我们使用数据时将数据压缩为更简单的类结构。给定您提供的JSON,这就是我的处理方法。

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

class Shape
{
    public int Id { get; set; }
    public string Type { get; set; }
    public List<List<double>> Coordinates { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

[JsonConverter(typeof(ShapeConverter))]
class Shape
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

List<Shape> shapes = JsonConvert.DeserializeObject<List<Shape>>(json);
Run Code Online (Sandbox Code Playgroud)

这是一个演示程序:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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)
Run Code Online (Sandbox Code Playgroud)

如果您想花更多的钱,可以为每个坐标使用Pointstruct而不是a List<double>,和/或可以为每种复杂形状的类型(例如Line,Polygon)创建实际的类层次结构,并由组成它们Points。如果需要,修改转换器以创建这些对象将不难。我会把那部分留给你。