In the process I do using the 'Where' method below, I reach the list named 'list1' in the json. I need to do the same operation without using the 'Where' method, only using 'SelectTokens' once.
When I try this(test2) I am only accessing the last item.
var test = jsonVal.SelectTokens("data.list1[*]").Where(x => x.SelectTokens("list2[?(@.value > 15)]").Count() != 0);
var test2 = jsonVal.SelectTokens($"data.list1[*].list2[?(@.value > 15)]");
ex json:
{
"data": {
"list1": [
{
"list2": [
{
"value": 20
}
]
},
{
"list2": [
{
"value": 10
}
]
}
]
}
}
Note: JSON can be confusing. Basically what I want is to be able to pass a specific part of my query into a variable.
Demo fiddle here.
You can use nested filter expressions to select all entries of list1
that have at least one matching entry of list2
like so:
var items = jsonVal.SelectTokens("data.list1[?(@.list2[?(@.value > 15)])]");
The returned items, when serialized, match the contents of test
as required:
[
{
"list2": [
{
"value": 20
}
]
}
]
Notes:
The inner expression list2[?(@.value > 15)]
selects all entries of list2 with value > 15.
The outer expression data.list1[?(@list2 query)]
selects all entries in list1 that have matching entries in list2.
I'm not sure that nested filter expressions work on all JSONPath implementations. If I try the above query + JSON on https://jsonpath.curiousconcept.com/, neither Stefan Goessner's JSONPath 0.8.3 nor Flow Communications's JSONPath 0.5.0 can evaluate the query.
The JSONPath proposal merely states that ?()
should applies a filter (script) expression "using the underlying script engine" which is quite ambiguous.
Demo fiddle here.