Reputation: 423
I have a JSON array:
[
1,
2,
3,
4
]
I want to create a Json Path expression that returns all but the last element of the array, i.e. the result is:
[
1,
2,
3
]
There are lots of examples of first N elements and last N elements, but not the above. I can't work out the syntax.
I am using System.Text.Json with JsonPath.Net (https://www.nuget.org/packages/JsonPath.Net/)
Upvotes: -1
Views: 100
Reputation: 116794
JsonPath.NET implements RFC 9535, and RFC 9535 includes the Array Slice Selector [start:end:step]
. When start
or end
are negative, they are interpreted as offsets from the array end:
Slice expression parameters start and end are not directly usable as slice bounds and must first be normalized. Normalization for this purpose is defined as:
FUNCTION Normalize(i, len): IF i >= 0 THEN RETURN i ELSE RETURN len + i END IF
Thus "$[0:-1]"
should return all but the last element of the array, and JsonPath.NET does seem to implement this correctly:
var jsonArray = JsonSerializer.SerializeToNode(new int[] { 1, 2, 3, 4} )!.AsArray();
var path = JsonPath.Parse("$[0:-1]");
var results = path.Evaluate(jsonArray);
var newArray = JsonSerializer.SerializeToNode(results.Matches.Select(m => m.Value))!.AsArray(); // [1,2,3]
Assert.That(new int [] { 1, 2, 3 }.SequenceEqual(newArray.Deserialize<int []>()!)); // PASSES
Demo fiddle here.
Upvotes: 1
Reputation: 8428
Syntax to support your use case doesn't exist in the JSON Path spec. You need a way to get the index of the current value.
We have an open issue for a proposal to add that in a potential next version, https://github.com/ietf-wg-jsonpath/draft-ietf-jsonpath-base/issues/516.
The other difficult part in this particular case is that you'd need to get the length of the parent array. Again, there's not a syntax for that.
Assuming you built custom functions key()
and parent()
, and you enabled math operations (in the parsing options), you might be able to do something like this:
$[key(@)<length(parent(@))-1]
Upvotes: 0