一尘不染

Json.NET JSONPath查询未返回预期结果

json

我正在使用Newtonsoft的Json.Net从以下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"
   }
]

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

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

可以,但是我显然对语法不够了解。这将返回一个空列表:

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

并且单个令牌选择器返回null:

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

我在https://jsonpath.curiousconcept.com/上尝试了几种不同的配置,看来我的查询语法确实坏了。

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

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

但是,此语法对于Json.Net似乎无效(也不适用于同一页面上的Goessner实现)。

有人看到我在做什么错吗?


阅读 175

收藏
2020-07-27

共1个答案

一尘不染

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

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

根据需要返回

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

工作。净提琴

经过实验,似乎jsonpath.curiousconcept.com上的JSONPath实现都不支持此语法,但是它在使用https://github.com/ashphy/jsonpath-
online-evaluator的jsonpath.com上可以正常工作。该JSONPath提案只是说是一个
脚本表达式,使用底层脚本引擎*
清楚地留下了一些解释的余地是否以及如何“应该”的工作。()
*


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

2020-07-27