【问题标题】:Running expression predicate on Newtonsoft.Json.Linq.JObject在 Newtonsoft.Json.Linq.JObject 上运行表达式谓词
【发布时间】:2016-08-17 15:21:15
【问题描述】:

我正在创建 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。我不确定我是否使用了正确的方法。有没有一种方法可以在对象上评估谓词?

【问题讨论】:

  • var x = list.Find(j =&gt; j.SelectToken("$[?(@.PositionType == 1)]")); 这应该是行,但是,你可能应该做一些更像list.Where(j =&gt; j["PositionType"] != null).First(j =&gt; j["PositionType"] == 1)
  • 如果您已经将它作为 .NET 类型,为什么不直接对集合执行 LINQ 查询呢?为什么要先转换成 JObject?
  • 我提供了上面的示例作为示例。我的意图是构建一个动态 Json 对象存储,并让调用者使用 json 路径提供过滤器。图书馆不会知道类型。

标签: c# json linq json.net jsonpath


【解决方案1】:

SelectTokens() documentationJSONPath 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. 

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

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

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

您可以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?

【讨论】:

  • Jayway 的 webapp 没有使用最新的 Gatling JsonPath 版本(0.6.4,一年多前发布)。我用最新的 0.6.7 进行了测试,两个表达式都正确匹配。
猜你喜欢
  • 1970-01-01
  • 2010-10-28
  • 1970-01-01
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多