使用Json.NET测试嵌套键

本文关键字:嵌套 测试 NET Json 使用 | 更新日期: 2023-09-27 18:05:40

我想过滤json编码字符串的响应流,如下所示:

{ "Key1" : {"key2":"value"},
  "key3" : "other values"
}

我想过滤具有key2值的项目,如下所示:

IDisposable valueQuery = globalEventStream
    .Select(e => JObject.Parse(e.EventArgs.Data))
    .Where(e => e["key1"]["key2"] != null)

但是这给了我错误

Cannot access child value on Newtonsoft.Json.Linq.JValue

我能找到的解决这个问题的唯一方法是这样做:

IDisposable deathDisposable = globalEventStream
    .Select(e => JObject.Parse(e.EventArgs.Data))
    .Where(e => e["key1"] != null).Select(e => e["key1"])
    .Where(e => e["key2"] != null).Select(e => e["key2"])

是否有一种方法来过滤嵌套键与单个Where语句?

使用Json.NET测试嵌套键

您可以使用JToken.SelectTokens()在LINQ上运行嵌套查询到JSON对象:

var valueQuery = globalEventStream
    .Select(e => JObject.Parse(e.EventArgs.Data))
    .Where(o => o.SelectTokens("Key1.key2").Any());

样本小提琴。

JSONPath的规范在这里,它支持以下查询语法:

XPath   JSONPath    Description
/       $            the root object/element
.       @           the current object/element
/       . or []     child operator
..      n/a         parent operator
//      ..          recursive descent. JSONPath borrows this syntax from E4X.
*       *           wildcard. All objects/elements regardless their names.
@       n/a         attribute access. JSON structures don't have attributes.
[]      []          subscript operator. XPath uses it to iterate over element collections and for predicates. In Javascript and JSON it is the native array operator.
|       [,]         Union operator in XPath results in a combination of node sets. JSONPath allows alternate names or array indices as a set.
n/a     [start:end:step]    array slice operator borrowed from ES4.
[]      ?()         applies a filter (script) expression.
n/a     ()          script expression, using the underlying script engine.
()      n/a         grouping in Xpath 

。,用于以下JSON:

{ "Key1" : [{"NoKey2":"value"}, {"key2":"value"}],  "key3" : "other values" }

您可以使用通配符操作符*来测试数组中是否存在具有"key2"属性的任何项,如下所示:

var valueQuery = globalEventStream
    .Select(e => JObject.Parse(e.EventArgs.Data))
    .Where(o => o.SelectTokens("Key1[*].key2").Any());

这里Enumerable.Any()测试SelectTokens()查询是否找到超过0个结果——即,"Key1"数组中是否至少有一个条目具有"key2"属性。它比Enumerable.Count()更有效,因为它在返回一个项时立即停止计算。