我正在创建如下的JObject列表。我想使用查询表达式搜索集合。在下面的示例代码中,我使用Jsonpath查询查找类型为Buy(枚举Buy的int值为1)的所有位置对象。

List<JObject> list = new List<JObject>();
list.Add(JObject.FromObject(new Position() { PositionType = PositionType.Buy, Investment = new Investment() { InvestmentCode = "AAPL" } }));
list.Add(JObject.FromObject(new Position() { PositionType = PositionType.Sell, Investment = new Investment() { InvestmentCode = "AAPL" } }));

var x = list.Find(j =>
{
    JToken token =  j.SelectToken("$[?(@.PositionType == 1)]");
    return token != null;
});


SelectToken方法在谓词中返回null。我不确定我是否使用正确的方法。有没有一种方法可以对对象评估谓词?

最佳答案

SelectTokens() documentationJSONPath standard不能很好地解释它,但是可以说[?(script)]运算符定义为用于条件选择子对象。这是因为[?()]运算符实际上是嵌套在child / subscript运算符内部的脚本运算符的组合。从standard


  这是JSONPath语法元素与其XPath对应元素的完整概述和并排比较。

XPath    JSONPath    Description
/        . or []     child operator
[]       []          subscript operator. XPath uses it to iterate over element collections and for predicates. In Javascript and JSON it is the native array operator.
[]       ?()         applies a filter (script) expression.
n/a      ()          script expression, using the underlying script engine.



标准显示的[?()]运算符的唯一示例是匹配数组内对象的属性,然后返回这些对象。

因此,如果我使用SelectTokens()[{"PositionType": 1}]上执行"$[?(@.PositionType == 1)]",则返回一个对象,但是在{"PositionType": 1}上执行该操作(因为您尝试在Find()谓词中进行操作)不会返回任何内容。

Json.NET在解释该标准时并不完全特质。以下是尝试使用各种JSONPath解析器将{"PositionType": 1}"$[?(@.PositionType == 1)]"$..[?(@.PositionType == 1)]进行匹配的结果:


http://www.jsonquerytool.com/-均不匹配。
http://jsonpath.com/-均不匹配。
http://jsonpath.herokuapp.com/


“ Jayway”:-都匹配。
“加特林”-"$[?(@.PositionType == 1)]"匹配,$..[?(@.PositionType == 1)]错误。 (更新:使用Gatling版本0.6.7,两者都匹配。)
“ Nebhale”-均错误。
“ Goessner”-均不匹配。



您可以report an issue关于Json.NET的行为,但是鉴于实现之间的不一致,可能无法解决。与XPath相比,JSONPath标准可能无法很好地定义和满足您的需求。

另请参见Newtonsoft JSON SelectToken to get data from multiple parts of JSON document?How to select JToken based on multiple name candidates in JSONPath?

10-02 01:21