Search code examples
c#jsonjson.netjsonpath

Applying a JSON path with an expression filter to a non-array JSON element with Newtonsoft


I am trying to apply an JSON Path that only selects elements based on another element in the document.

For example, for the following JSON:

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

I want to only select SomeFieldC when SomeFieldA exists and is equal to X

I've tried running the following expression $.SomeFieldB[?($.SomeFieldA == 'X')].SomeFieldC and even though it works in some implementations (e.g. https://jsonpath.herokuapp.com/), it doesn't seem to work with Newtonsoft (JSON.NET)

The following code doesn't work for me (returns an empty list):

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())));

I know I can get this behavior with a simple LINQ query, but I have a framework that can only work with JSON paths and so I want to find a JSON path that will accomplish that.


Solution

  • My guess is that Newtonsoft doesn't like the $ inside the filter expression. This doesn't seem to be tested in the implementation comparison project.

    We have decided it's valid to use it, however, as part of the effort to standardize JSON Path.

    If you need a .Net implementation that supports this, check out my JsonPath.Net.

    If you're stuck with Newtonsoft, try https://www.nuget.org/packages/JsonPath/ instead. No guarantees on it though.