我想过滤一个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
语句过滤嵌套键?
答案 0 :(得分:3)
您可以使用JToken.SelectTokens()
在LINQ to JSON对象上运行嵌套查询:
var valueQuery = globalEventStream
.Select(e => JObject.Parse(e.EventArgs.Data))
.Where(o => o.SelectTokens("Key1.key2").Any());
示例fiddle。
JSONPath的规范是here,并支持以下查询语法:
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()
查询是否发现结果多于零 - 即,"Key1"
数组中至少有一个条目"key2"
属性。它比执行Enumerable.Count()
更有效,因为它会在返回一个项目后立即停止评估。