【问题标题】:Testing for nested keys with Json.NET?使用 Json.NET 测试嵌套键?
【发布时间】:2016-09-05 18:31:39
【问题描述】:

我想过滤这样的 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 语句过滤嵌套键?

【问题讨论】:

    标签: c# json linq


    【解决方案1】:

    您可以使用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() 更有效,因为它会在返回一个项目后立即停止评估。

    【讨论】:

    • 添加Any()有什么作用?
    猜你喜欢
    • 2021-06-01
    • 2016-01-17
    • 1970-01-01
    • 2011-08-21
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    相关资源
    最近更新 更多