Json.NET JSONPath 查询未返回预期结果 [英] Json.NET JSONPath query not returning expected results

查看:20
本文介绍了Json.NET JSONPath 查询未返回预期结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Newtonsoft 的 Json.Net 从以下 json 中选择节点:

I'm using Newtonsoft's Json.Net to select nodes from the following json:

{  
   "projects":[  
      {  
         "name":"Project 1",
         "client":{  
            "code":"ABC",
            "name":"Client 1"
         }
      },
      {  
         "name":"Project 2",
         "client":{  
            "code":"DEF",
            "name":"Client 2"
         }
      },
      {  
         "name":"Project 3",
         "client":{  
            "code":"GHI",
            "name":"Client 3"
         }
      }
   ]
}

以下 c# 片段

//json is a JObject representation of the json listed above
var clients =  json.SelectTokens("$.projects[*].client");

产量:

[  
   {  
      "code":"ABC",
      "name":"Client 1"
   },
   {  
      "code":"DEF",
      "name":"Client 2"
   },
   {  
      "code":"GHI",
      "name":"Client 3"
   }
]

这很酷,现在,我想做的是按客户端代码过滤,我认为

Which is cool, now, what I'd like to do is filter by client code, I would think that

$.projects[*].client[?(@.code == 'DEF')]

会起作用,但我显然对语法不够了解.这将返回一个空列表:

would work, but I obviously don't understand the syntax well enough. This returns an empty list:

 var test1 =  json.SelectTokens("$.projects[*].client[?(@.code == 'DEF')]").ToList();

并且单标记选择器返回一个空值:

And the single token selector returns a null:

  var test2 =  json.SelectToken("$.projects[*].client[?(@.code == 'DEF')]");

我在 https://jsonpath.curiousconcept.com/ 上尝试了几种不同的配置,这似乎是我的查询语法确实被破坏了.

I tried a few different configurations on https://jsonpath.curiousconcept.com/ and it seems my query syntax is indeed broken.

使用 Flow Communications 的 JSONPath 0.3.4 实现(在上面的链接上)我可以使用

Using Flow Communications' JSONPath 0.3.4 implementation (on the above link) I can get the client using

$..[?(@.code == 'DEF')]

但是,这种语法似乎对 Json.Net 无效(同一页面上的 Goessner 实现也无效).

however, this syntax does not seem valid for Json.Net (nor the Goessner implementation on the same page).

有人知道我做错了吗?

推荐答案

Json.NET 的 JSONPath parser 允许过滤器(脚本)表达式 [?( )] 查询候选对象子对象内的嵌套属性数组项.因此

Json.NET's JSONPath parser allows the filter (script) expression [?( )] to query for nested properties inside child objects of the candidate array item(s). Thus

var test = json.SelectTokens(@"$.projects[?(@.client.code == 'DEF')].client");

根据需要返回,

[
  {
    "code": "DEF",
    "name": "Client 2"
  }
]

工作 .Net fiddle.

经过实验,jsonpath.curiousconcept.com 上的 JSONPath 实现似乎都不支持这种语法,但是它在使用 jsonpath.com 上正常工作-online-evaluator" rel="nofollow noreferrer">https://github.com/ashphy/jsonpath-online-evaluator.JSONPath 提议 只是声明 () 是一个脚本表达式,使用底层脚本引擎,这显然为这个应该"是否以及如何工作留下了一些解释空间.

Upon experimentation it seems none of the JSONPath implementations at jsonpath.curiousconcept.com support this syntax, however it works correctly at jsonpath.com which uses https://github.com/ashphy/jsonpath-online-evaluator. The JSONPath proposal simply states that () is a script expression, using the underlying script engine which clearly leaves some room for interpretation as to whether and how this "should" work.

问题中使用的过滤器显然不适用于 Json.NET,因为从 10.0.3 版本开始,它仅正式支持将过滤器应用于数组项而不是直接应用于对象 - 请参阅 Issue #1256: 用于讨论的对象的 JSONPath 脚本没有正确执行.(虽然有时可以找到巧妙的解决方法,例如在 this answer 中.)然而,在过滤器中使用嵌套属性似乎打算工作(并且确实工作).

The filters used in the question apparently do not work with Json.NET because, as of version 10.0.3, it only officially supports applying filters to array items and not directly to objects -- see Issue #1256: JSONPath scripts not executing correctly for objects for a discussion. (Though sometimes cunning workarounds can be found, for instance in this answer.) Using nested properties inside filters, however, seems to be intended to work (and does work).

这篇关于Json.NET JSONPath 查询未返回预期结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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