It's not well explained by the SelectTokens()
documentation or the JSONPath standard, but the [?(script)]
operator is arguably defined to be for conditional selection of child objects. This is because the [?()]
operator is actually a combination of the script operator nested inside the child/subscript operator. From the standard:
Here is a complete overview and a side by side comparison of the JSONPath syntax elements with its XPath counterparts.
XPath JSONPath Description
/ . or [] child operator
[] [] subscript operator. XPath uses it to iterate over element collections and for predicates. In Javascript and JSON it is the native array operator.
[] ?() applies a filter (script) expression.
n/a () script expression, using the underlying script engine.
The only examples the standard shows of the [?()]
operator is in matching properties of objects inside arrays, and returning those objects.
Thus if I do SelectTokens()
on [{"PositionType": 1}]
using "$[?(@.PositionType == 1)]"
then one object is returned, but doing it on {"PositionType": 1}
(as you are trying to do inside your Find()
predicate) returns nothing.
Json.NET is not entirely idiosyncratic in its interpretation of the standard. Here are the results of trying to match {"PositionType": 1}
against "$[?(@.PositionType == 1)]"
and $..[?(@.PositionType == 1)]
using various JSONPath parsers:
You could report an issue about Json.NET's behavior, but given the inconsistency between implementations it might not get addressed. The JSONPath standard simply may not be well-defined and stable enough for your needs as compared to XPath at this point.
See also Newtonsoft JSON SelectToken to get data from multiple parts of JSON document? and How to select JToken based on multiple name candidates in JSONPath?.