我正在创建如下的JObject列表。我想使用查询表达式搜索集合。在下面的示例代码中,我使用Jsonpath查询来查找所有类型为Buy的位置对象(enum 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。我不确定我是否使用正确的方法。有没有办法在对象上评估谓词?
答案 0 :(得分:1)
SelectTokens()
documentation或JSONPath standard没有很好地解释,但[?(script)]
运算符可以定义为条件选择子对象。这是因为[?()]
运算符实际上是嵌套在子/下标运算符中的脚本运算符的组合。来自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()
内所做的那样1}}谓词)什么也不返回。
Json.NET对标准的解释并不完全特殊。以下是使用各种JSONPath解析器尝试将{"PositionType": 1}
与"$[?(@.PositionType == 1)]"
和$..[?(@.PositionType == 1)]
匹配的结果:
"$[?(@.PositionType == 1)]"
匹配,$..[?(@.PositionType == 1)]
错误。 (更新:Gatling版本0.6.7,两者都匹配。)你可以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?。