在Newtonsoft.Json.Linq.JObject上运行表达式谓词
本文关键字:运行 表达式 谓词 JObject Newtonsoft Json Linq | 更新日期: 2023-09-27 18:02:59
我正在创建如下所示的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。我不确定我是否使用了正确的方法。是否有一种方法可以在对象上计算谓词?
SelectTokens()
文档或JSONPath标准没有很好地解释这一点,但是[?(script)]
操作符可以说被定义为用于子对象的条件选择。这是因为[?()]
操作符实际上是嵌套在子操作符/下标操作符中的脚本操作符的组合。来自标准:
这里是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.
标准显示的[?()]
操作符的唯一示例是匹配数组内对象的属性,并返回这些对象。
因此,如果我使用"$[?(@.PositionType == 1)]"
在[{"PositionType": 1}]
上做SelectTokens()
,那么返回一个对象,但是在{"PositionType": 1}
上做(正如你试图在Find()
谓词内做的那样)什么也不返回。
Json。NET对标准的解释并不完全是特殊的。下面是尝试使用各种JSONPath解析器将{"PositionType": 1}
与"$[?(@.PositionType == 1)]"
和$..[?(@.PositionType == 1)]
匹配的结果:
- http://www.jsonquerytool.com/-都不匹配。
- http://jsonpath.com/-都不匹配。
- http://jsonpath.herokuapp.com/
- "Jayway": -两者都匹配。
- "Gatling" -
"$[?(@.PositionType == 1)]"
匹配,$..[?(@.PositionType == 1)]
错误。(更新:与Gatling版本0.6.7,两者匹配。) - "Nebhale" -两个错误。
- "Goessner" -都不匹配。
你可以报告Json的问题。. NET的行为,但鉴于实现之间的不一致性,它可能无法得到解决。此时,与XPath相比,JSONPath标准可能还不够定义良好,也不够稳定,无法满足您的需求。
参见Newtonsoft JSON SelectToken从JSON文档的多个部分获取数据?.