【问题标题】:Applying a JSON path with an expression filter to a non-array JSON element with Newtonsoft使用 Newtonsoft 将带有表达式过滤器的 JSON 路径应用于非数组 JSON 元素
【发布时间】:2021-07-25 07:54:12
【问题描述】:

我正在尝试应用仅基于文档中的另一个元素选择元素的 JSON 路径。

例如,对于以下 JSON:

{
    'SomeFieldA': 'X',
    'SomeFieldB': {
         'SomeFieldC': 'Y'
     }
}

SomeFieldA 存在且等于X 时,我只想选择SomeFieldC

我尝试运行以下表达式 $.SomeFieldB[?($.SomeFieldA == 'X')].SomeFieldC,尽管它在某些实现中有效(例如 https://jsonpath.herokuapp.com/),但它似乎不适用于 Newtonsoft (JSON.NET)

以下代码对我不起作用(返回一个空列表):

var jsonObject = JObject.Parse(@"
    {
        'SomeFieldA': 'X',
        'SomeFieldB': {
            'SomeFieldC': 'Y'

        }
    }");

Console.WriteLine(string.Join(
    Environment.NewLine,
    jsonObject.SelectTokens("$.SomeFieldB[?($.SomeFieldA == 'X')].SomeFieldC")
        .Select(token => token.ToString())));

我知道我可以通过一个简单的 LINQ 查询来获得这种行为,但我有一个只能使用 JSON 路径的框架,所以我想找到一个可以实现这一目标的 JSON 路径。

【问题讨论】:

    标签: c# json json.net jsonpath


    【解决方案1】:

    我的猜测是 Newtonsoft 不喜欢过滤器表达式中的$。这似乎没有在implementation comparison project 中进行测试。

    我们已经决定使用它是有效的,但是,作为effort to standardize JSON Path 的一部分。

    如果您需要支持此功能的 .Net 实现,请查看我的 JsonPath.Net

    如果您不喜欢 Newtonsoft,请改用 https://www.nuget.org/packages/JsonPath/。但不能保证。

    【讨论】:

    • 如果不将所有内容从 Newtonsoft 迁移到 System.Text.Json ,我似乎无法做到这一点,呵呵
    • 似乎.NET 5 System.Text.Json 不支持修改 JSON,这是我的一个不相关的要求,所以它不是一个可行的选择
    • 可以得到修改JSON的效果,但是必须通过重复的字符串化和解析,这是我的库现在所做的。 JsonNode 是 .Net 6 应该附带的一个概念。
    • 在我的 JsonPatch.Net 内部,我定义了一个 EditableJsonElement,用于在构建最终输出之前跟踪更改。您可以在github.com/gregsdennis/json-everything/tree/master/… 查看源代码。它还有一个辅助类。
    • 如果用另一个使用 Newtonsoft 的选项编辑答案。
    【解决方案2】:

    这是根据条件SomeFieldA == X选择SomeFieldC的简单方法-

    var result = jObject["SomeFieldA"]?.ToString() == "X" ? 
                 jObject["SomeFieldB"]?["SomeFieldC"]?.ToString() : "";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-18
      • 1970-01-01
      • 2016-03-06
      • 2020-11-05
      • 2019-11-13
      • 2014-11-20
      • 2017-09-05
      • 1970-01-01
      相关资源
      最近更新 更多