我有一个这样的JSON:

{
    "options": [
        {
            "price": 217,
            "quantity": 2
        },
        {
            "price": 63,
            "quantity": 5
        }
    ]
}

我想用JsonPath对其进行查询,以获得"Options"数组中每个元素的"价格"和"数量"的乘积.

我用这site来玩弄语法.我实际上找到了一种方法:

options[?(@.result = @.price * @.quantity)].result

此语法向每个元素添加一个属性‘Result’,并将产品存储在其中,如下所示:

[
  {
    "price": 217,
    "quantity": 2,
    "result": 434  // yay!
  },
  {
    "price": 63,
    "quantity": 5,
    "result": 315  // yay!
  }
]

所以最终的结果就是我想要的:

[
  434,
  315
]

我真的不需要设置任何属性.我只想要这样的结果.

问题是-它不能在C#应用程序(使用Newtonsoft.Json)中工作.它无法解析该查询. 我事先try 在JSON中引入该属性,但也不起作用.

json = JObject.Parse(@"{}"); // same JSON as above

var result = json.SelectTokens("options[?(@.result = @.price * @.quantity)].result"); // exception

你能帮我弄清楚吗?

Note:我只有用户界面可供我支配.不能访问代码,不能访问LINQ,不能调用API.我只是碰巧知道底层的实现.

推荐答案

在相当长的一段时间内,JSONPath语法并没有很好地标准化.因此,一种实现及其支持的内容可能与另一种有很大不同(特别是您try 过的在线工具--我发现它比我使用的JSONPath实现宽松得多).例如,我通常用来作为语法参考的this站点似乎缺少您try 过的选项.this online validator不会像您预期的那样处理该查询表达式.

请注意,正如JToken.SelectToken Method号文件中所述:

使用JPath表达式 Select JToken. Select 与对象路径匹配的令牌.

因此,可以说它根本不应该支持这种语法.根据Newtonsoft.Json github repo个测试中的测试,这样的语法没有得到测试(至少在我看过的测试中是这样),可以肯定地认为它不受支持.

因此,我建议只迭代数组的元素并计算所需的值:

var results = new List<int>();
foreach (var elem in json["options"])
{
    results.Add(elem["price"].Value<int>() * elem["quantity"].Value<int>());
}

还要注意,有pending IETF specification个,根据它,JSONPath是仅查询的,不支持这样的语法.

Csharp相关问答推荐

LINQ无法翻译SQLFunctions方法

编写DataAnnotations自定义验证器的多种方法

如何在C#中删除一个特殊字符,如"使用Regex"

为什么在ANTLR4中会出现不匹配的输入错误?""

dotnet集合中内部数组的局部变量副本的用途是什么?'

在具有主构造函数的类中初始化属性时出现警告

Quartz调度程序不调用作业(job)类

如何将不同类型的扩展参数的javascript函数转换成C#风格?

Thad.Sept()vs Task.Delay().Wait()

为什么Regex.IsMatch(";\\t";,";\\t";)返回FALSE而不是TRUE?

在C#中反序列化/序列化具有混合元素顺序的XML时出现问题

当索引和外键是不同的数据类型时,如何设置导航属性?

有没有更好的方法来在CosmosDB上插入非id?

单元测试类型为HttpClient with Microsoft.Extensions.Http.Resilience

Blazor:搜索框在第一次搜索时不搜索

Autofac -动态实例化:手动传递构造函数

删除MudRadio时,MudRadioGroup未 Select 正确的MudRadio

无法向Unity注册Microsoft Logger

最小API定义的Swagger标头参数

将ValueTask发送给调用者