我正在创建如下的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()
documentation或JSONPath 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?。