JSON.NET-选择所有对象 [英] JSON.NET - Select All Objects

查看:119
本文介绍了JSON.NET-选择所有对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种使用Json.NET在JObject中选择所有对象的方法.简而言之,如果我有以下JSON:

I am looking for a method to select ALL the objects in the JObject using Json.NET. So in short, if I had the following JSON:

{
  "someCar" : {
    "id" : "3",
    "model" : "M7",
    "engine" : "FI V8",
  },
  "name" : "carparkone",
  "id" : "1",
  "cars" : [
    {
      "id" : "1",
      "model" : "s60",
      "engine" : "i5",
    },
    {
      "id" : "2",
      "model" : "m3",
      "engine" : "FI V6",
    },
    {
      "id" : "3",
      "model" : "M7",
      "engine" : "FI V8",
    }
  ]
}

我将运行一些命令以获取其中所有对象的数组,即{}块中的所有对象.

I would run some command to get an array of all the objects in it, i.e. anything in {} blocks.

理想情况下,我会找到someProp具有some value的所有对象,因此只有具有engine属性且值为V6的对象.

Ideally, I would find all the objects where someProp has some value, so only objects that have a property engine with a value of V6.

tl; dr问题:

  1. 如何获取嵌套在JObject中的所有对象的列表?
  2. (奖励)仅获得具有特定属性的对象.

推荐答案

您可以使用

You can use LINQ to JSON to parse and filter JSON objects when there is no predefined schema.

首先,使用以下命令将JSON解析为 JObject JToken.Parse() .然后,您可以使用 JContainer.DescendantsAndSelf() 遍历该根对象,及其所有后代标记(按文档顺序). (或者,如果要跳过根对象,请使用 JContainer.Descendants() .)然后可以使用 返回所有对象(无论是否嵌套):

First, parse your JSON to a JObject using JToken.Parse(). Then you can use JContainer.DescendantsAndSelf() to iterate through that root object, and all descendant tokens of it, in document order. (Or use JContainer.Descendants() if you want to skip the root object.) Then you can filter then using using .OfType<JObject>() to return all objects whether nested or not:

var root = JObject.Parse(jsonString;
var allObjs = root.DescendantsAndSelf()
    .OfType<JObject>()
    .ToArray();

要按某些值过滤,可以添加其他

To filter by some value, you can add an additional Where() clause as shown in the following extension method:

public static partial class JTokenExtensions
{
    public static JObject [] FilterObjects<T>(this JObject root, string someProp, T someValue)
    {
        var comparer = new JTokenEqualityComparer();
        var someValueToken = JToken.FromObject(someValue);
        var objs = root.DescendantsAndSelf()
            .OfType<JObject>()
            .Where(t => comparer.Equals(t[someProp], someValueToken))
            .ToArray();

        return objs;
    }
}

然后执行:

var filteredObjs = root.FilterObjects(someProp, someValue);

要使FilterObjects()完全通用,我将所需值序列化为JToken,然后使用 JTokenEqualityComparer 将实际值与所需值进行比较.如果您知道所需的值是原始类型,则可以执行以下操作:

To make FilterObjects() be completely generic, I serialize the desired value to a JToken then use JTokenEqualityComparer to compare the actual value with the desired value. If you know that the desired value is a primitive type, instead you can do:

public static partial class JTokenExtensions
{
    public static bool IsNull(this JToken token)
    {
        return token == null || token.Type == JTokenType.Null;
    }

    public static JObject[] FilterObjectsSimple<T>(this JObject root, string someProp, T someValue)
    {
        var comparer = EqualityComparer<T>.Default;
        var objs = root.DescendantsAndSelf()
            .OfType<JObject>()
            .Where(t => { var v = t[someProp]; return v != null && (someValue == null ? v.IsNull() : comparer.Equals(v.ToObject<T>(), someValue)); })
            .ToArray();

        return objs;
    }
}

示例小提琴.

注意-您还可以考虑使用 SelectTokens() ,支持 JSONPath查询语法,例如:

Note - you might also consider using SelectTokens(), which supports the JSONPath query syntax, e.g.:

var someProp = "id";
var someValue = "3";
var filterString = string.Format(@"..*[?(@.{0} == '{1}')]", someProp, someValue);
var filteredObjs = root.SelectTokens(filterString).ToArray();

但是,您的JSON包含直接嵌套在其他对象内部的对象,并且Newtonsoft的JSONPath实现没有找到这样的直接嵌套的对象,如

However, your JSON includes objects nested directly inside other objects, and Newtonsoft's implementation of JSONPath does not find such directly nested objects, as explained in JSONPath scripts not executing correctly for objects #1256.

这篇关于JSON.NET-选择所有对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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