在Newtonsoft.Json.Linq.JObject

时间:2016-08-17 15:21:15

标签: c# json linq json.net jsonpath

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

1 个答案:

答案 0 :(得分: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. 

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

因此,如果我使用SelectTokens()[{"PositionType": 1}]进行"$[?(@.PositionType == 1)]",则会返回一个对象,但会在{"PositionType": 1}上执行此操作(正如您在Find()内所做的那样1}}谓词)什么也不返回。

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

  • http://www.jsonquerytool.com/ - 两者都不匹配。
  • http://jsonpath.com/ - 两者都不匹配。
  • http://jsonpath.herokuapp.com/
    • &#34; Jayway&#34;: - 两者都匹配。
    • &#34;格林&#34; - "$[?(@.PositionType == 1)]"匹配,$..[?(@.PositionType == 1)]错误。 (更新:Gatling版本0.6.7,两者都匹配。)
    • &#34; Nebhale&#34; - 两个错误。
    • &#34; Goessner&#34; - 两者都不匹配。

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