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

时间:2017-07-25 08:29:28

标签: c# json json.net jsonpath

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

c++

以下c#片段

{  
   "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"
         }
      }
   ]
}

收率:

//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')]

单个标记选择器返回null:

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

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

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

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

但是,这种语法似乎对Json.Net不起作用(也不是同一页面上的Goessner实现)。

任何人都能看到我做错了什么?

1 个答案:

答案 0 :(得分:3)

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

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

根据需要返回

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

工作.Net fiddle

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

question中使用的过滤器显然不适用于Json.NET,因为从版本10.0.3开始,它只正式支持将过滤器应用于数组项而不是直接应用于对象 - 请参阅{{3讨论。 (虽然有时可以找到狡猾的解决方法,例如在Issue #1256: JSONPath scripts not executing correctly for objects中。)然而,在过滤器中使用嵌套属性似乎可以工作(并且确实有效)。