从json或jarray元素中提取值

时间:2019-07-04 19:24:33

标签: c# json json.net

我有JSON数组,如:

[
    {
        "type": "type1",
        "id": "id1",
        "properties": 
        {
            "sales": 
            [
                {
                    "name": "name1",
                    "requested_date": "2019-06-28"
                }
            ]
        }
    },
    {
        "type": "type1",
        "id": "id2",
        "properties": 
        {
            "sales": 
            [
                {
                    "name": "name2",
                    "requested_date": "2019-06-28"
                }
            ]
        }
    },
    {
        "type": "type1",
        "id": "id3",
        "properties": 
        {
            "sales": 
            [
                {
                    "name": "name3",
                    "requested_date": "2019-06-29"
                }
            ]
        }
    }
]

我想先通读它以提取出所请求日期的所有唯一值,因此在这种情况下,我将拥有“ 2019-06-28”,“ 2019-06-29”。

第二,我将需要能够选择与指定的所请求日期的选定值有关的所有条目。我已经有一个POCO可以用于销售,一个POCO可以用于整个条目,但是属性只是对象字典,因为它可以是任何东西,例如在这种情况下就是销售。

我在JArray中有我的JSON:

var stringCachedAddresses = JsonConvert.SerializeObject(cachedAddresses);
var parsedObject = JArray.Parse(stringCachedAddresses);

我只是不知道如何导航到每个条目的requested_date,如果不存在该值,则将其添加到列表中,也许我无法弄清某种LINQ。

我可以获得所有销售的清单:

var parsedProperties = (from f in parsedObject
                        select f["properties"]["sales"]).ToList();

如何才能从parsedProperties中读取或直接获取requested_date的值?

2 个答案:

答案 0 :(得分:4)

假设您的销售POCO 如下所示:

public class Sales
{
    public string name { get; set; }
    public string requested_date { get; set; }
}

然后,您可以在层次结构中找到具有指定"sales"的所有requested_date对象,并通过组合查询和对JToken.ToObject<Sales>的调用来对它们进行反序列化,以对每个选定项进行反序列化:

// Your requested date
var requested_date = "2019-06-28";

// Construct a JSONPath query
var pathTemplate = "[*].properties.sales[?(@.requested_date == '{0}')]";
var path = string.Format(pathTemplate, requested_date);

// Query for and deserialize all sales from the specified requested date
var query = parsedObject.SelectTokens(path)
    .Select(t => t.ToObject<Sales>());

// Materialize the query as a list.
var list = query.ToList();

类似地,您可以找到所有不同的requested_date值,如下所示:

// Query for all values of requested_date, convert them to strings, and take all distinct values:
var query = parsedObject.SelectTokens("[*].properties.sales[*].requested_date")
    .Select(t => t.ToString()) 
    .Distinct();

// Materialize the query as a list.
var list = query.ToList();

注意:

  1. *通配符运算符选择所有数组元素。

  2. ?(<expression>)过滤器运算符应用过滤器表达式(使用Json.NET的filter syntax)来选择指定的数组元素-这里是具有指定请求日期的元素。

  3. 有关JSONPath语法的概述,请参见JSONPath - XPath for JSON

  4. 如果属性"sales"的名称不固定,则可以对属性名称使用通配符,例如:

    "[*].properties.*[?(@.requested_date == '{0}')]";
    

    "[*].properties.*[*].requested_date"
    

演示小提琴here

答案 1 :(得分:0)

我设法得到了不同的request_date,尽管看起来并不复杂:

var parsedObject = JArray.Parse(stringCachedAddresses);
var parsedProperties = (from f in parsedObject
                        select f["properties"]["sales"]);
var parsedForSales = (from s in parsedProperties.Children()["requested_date"]
                      select s).Distinct().ToList();

我的主要问题仍然是如何根据所需的request_date提取JSon条目?