Запуск предиката выражения в Newtonsoft.Json.Linq.JObject
Я создаю список JObject, как показано ниже. Я хотел бы найти коллекцию, используя выражение запроса. В приведенном ниже примере кода я использую запрос Jsonpath, чтобы найти все объекты позиции типа Buy (enum Buy имеет значение int 1)
List<JObject> list = new List<JObject>();
list.Add(JObject.FromObject(new Position() { PositionType = PositionType.Buy, Investment = new Investment() { InvestmentCode = "AAPL" } }));
list.Add(JObject.FromObject(new Position() { PositionType = PositionType.Sell, Investment = new Investment() { InvestmentCode = "AAPL" } }));
var x = list.Find(j =>
{
JToken token = j.SelectToken("$[?(@.PositionType == 1)]");
return token != null;
});
Метод SelectToken возвращает нулевое значение в предикате. Я не уверен, что использую правильный метод. Есть ли способ оценки предиката на объекте?
1 ответ
Это не очень хорошо объясняется SelectTokens()
документация или стандарт JSONPath, но [?(script)]
оператор может быть определен для условного выбора дочерних объектов. Это потому что [?()]
оператор на самом деле является комбинацией оператора сценария, вложенного в оператор дочерний / нижний индекс. Из стандарта:
Вот полный обзор и сравнение элементов синтаксиса JSONPath с его аналогами XPath.
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.
Единственными примерами стандартных шоу из [?()]
оператор находится в сопоставлении свойств объектов внутри массивов и возвращает эти объекты.
Таким образом, если я сделаю SelectTokens()
на [{"PositionType": 1}]
с помощью "$[?(@.PositionType == 1)]"
тогда один объект возвращается, но делает это на {"PositionType": 1}
(как вы пытаетесь сделать внутри вашего Find()
предикат) ничего не возвращает.
Json.NET не совсем уникален в своей интерпретации стандарта. Вот результаты попыток совпадения {"PositionType": 1}
против "$[?(@.PositionType == 1)]"
а также $..[?(@.PositionType == 1)]
используя различные парсеры JSONPath:
- http://www.jsonquerytool.com/ - ни один не соответствует.
- http://jsonpath.com/ - ни один не соответствует.
- http://jsonpath.herokuapp.com/
- "Jayway": - оба совпадают.
- "Гатлинг" -
"$[?(@.PositionType == 1)]"
Матчи,$..[?(@.PositionType == 1)]
ошибки. (Обновление: с версией Gatling 0.6.7, оба совпадают.) - "Небхале" - обе ошибки.
- "Гесснер" - ни один не совпадает.
Вы можете сообщить о проблеме, связанной с поведением Json.NET, но, учитывая несоответствие между реализациями, она может быть не решена. Стандарт JSONPath может быть недостаточно четким и недостаточно стабильным для ваших нужд по сравнению с XPath на данный момент.
См. Также Newtonsoft JSON SelectToken для получения данных из нескольких частей документа JSON? и Как выбрать JToken на основе нескольких имен кандидатов в JSONPath?,