JSONPath-запросы к JSON

Проверить JSONPath-выражение на своём JSON: обращение к ключам и индексам, перебор массивов и объектов, рекурсивный поиск, срезы и фильтры. Показывает найденные значения и путь до каждого. Всё считается в браузере.

JSON

Запрос

Начинается с $. Выражение в примерах ниже подставляется по нажатию

Примеры выражений

Нажмите на выражение, чтобы подставить его в поле выше.

ВыражениеЧто находит
Значение вложенного поля: точка — шаг вглубь по ключам
Поле name у всех элементов массива: [*] — перебор
Первый элемент массива целиком; [1] — второй, [-1] — последний
Срез: элементы с 0 по 1, правый индекс не входит
Все значения price на любой глубине, включая discount.price
Фильтр: элементы массива, у которых price меньше 100

Результат

найдено значений: 0

Вставьте JSON в поле выше — найденные значения появятся здесь.

Зачем проверять JSONPath-выражения

JSONPath нужен там, где из документа требуется не весь документ, а несколько значений: список идентификаторов из ответа API, все цены из дерева категорий, адреса почты из выгрузки. Написать такое выражение вслепую трудно: имена ключей и глубина вложенности в чужом JSON угадываются плохо, а ошибка в одном символе даёт не часть данных, а пустой результат. Инструмент показывает, что выражение действительно находит: каждое значение, путь до него в точечной нотации и тип — по типу сразу видно, что из выгрузки пришло строкой там, где ожидалось число.

Выражение разбирается один раз и затем применяется к документу, поэтому его можно править и смотреть на результат сразу, не перезагружая страницу. Ошибка в выражении объясняется по-русски и с позицией: под полем отмечается символ, на котором разбор остановился, — это быстрее, чем искать лишнюю скобку глазами. Готовые примеры подставляются в поле одним нажатием: удобно, когда нужно вспомнить, как пишется срез или фильтр, и сразу проверить синтаксис на своём документе.

Считает инструмент в браузере: JSON не отправляется на сервер и не сохраняется. Поддерживается не весь язык, а его ядро — обращение к ключам, индексы, перебор, рекурсивный поиск, срезы, списки индексов и фильтры по значению поля. Функций вроде length(), регулярных выражений и скриптовых выражений здесь нет: они относятся уже не к выборке, а к вычислениям, и их место — в коде, куда рабочее выражение и переносят.

Частые вопросы

Что такое JSONPath и чем он удобнее ручного обхода?

JSONPath — язык запросов к JSON, записанный одной строкой: как XPath для XML или как путь к файлу для папок. Ручной обход — это вложенные циклы в коде или поиск глазами по свёрнутому документу: чем глубже структура, тем больше кода и тем легче пропустить ветку. Выражение `$.items[?(@.price < 100)].name` заменяет такой обход целиком и, что важнее, его видно и можно проверить: подставили другое условие — сразу получили другой результат, ничего не переписывая. Здесь это используют как проверку: подобрать выражение на реальном документе, увидеть найденные значения и пути до них, а потом перенести рабочее выражение в код.

Какой синтаксис поддерживается, а какой нет?

Поддерживается ядро языка: `$` — корень, `.ключ` и `['ключ']` — обращение к полю, `[0]` и `[-1]` — индексы массива, `[*]` — перебор элементов массива и значений объекта, `..ключ` и `..[*]` — рекурсивный поиск, `[0:2]` и `[0:5:2]` — срезы с шагом, `[0,2]` — список индексов, `[?(@.поле)]` — проверка существования поля и `[?(@.поле == значение)]` со сравнениями `==`, `!=`, `<`, `<=`, `>`, `>=`. Не поддерживается то, что относится уже не к выборке, а к вычислениям: регулярные выражения в фильтрах, функции вроде `length()`, `count()` и `min()`, скриптовые выражения вида `[(@.length-1)]`. Их нет намеренно — вместо них в фильтре можно только сравнить значение поля с константой или проверить, что поле вообще есть. Если выражение требует функции или регулярного выражения, его придётся выполнить в коде после выборки.

Как отфильтровать массив по значению поля?

Фильтр пишется в квадратных скобках после имени массива: `$.items[?(@.price < 100)]`. Знак `?` начинает фильтр, `@` обозначает текущий элемент, дальше идёт путь до поля внутри элемента и оператор со значением. Так `$.items[?(@.tags)]` вернёт элементы, у которых поле `tags` есть вообще — это проверка существования, без значения. Сравнивать можно с числом, строкой в одинарных или двойных кавычках, а также с `true`, `false` и `null`. Строки сравниваются по алфавиту, а `==` и `!=` терпимы к числу, записанному строкой: `"89"` и `89` для них одно и то же — так выглядят выгрузки, где все значения пришли текстом.

Что делает рекурсивный поиск с двумя точками и почему он медленный?

`$..price` означает «найти поле price где угодно в документе»: инструмент обходит не один уровень, а всё дерево сразу — каждый объект, каждый массив, каждого потомка на любой глубине. Отсюда и польза, и цена: ключ может лежать в неожиданной ветке, и заглянуть туда заранее вы не можете, зато обход читает весь документ целиком, даже если нужное значение нашлось в первом же узле. Обычный путь `.items[0].price` идёт прямо по известным ключам и почти не тратит времени. Поэтому на документе в мегабайт и больше рекурсивный поиск заметно тормозит, и лучше заменить его точным путём, если структура известна.

Как читать путь до найденного значения?

Путь в таблице записан в той же точечной нотации, что и выражение: `$.items[1].price` читается как «корень, поле items, второй элемент массива, поле price». Индексы в квадратных скобках — позиции в массивах, они нумеруются с нуля. Ключ, который точкой не записать (пробел, дефис, точка внутри имени), выводится скобкой: `$['имя с пробелом'].value` — так его можно скопировать обратно в поле выражения и получить то же самое значение. Этот путь — готовая подсказка для точного запроса вместо рекурсивного: нашлось лишнее при обходе всего документа, скопируйте путь до нужного и замените им `..`.

Где JSONPath применяют на практике?

Везде, где из большого ответа или выгрузки нужно вытащить несколько полей: вытащить идентификаторы из ответа API, собрать список адресов почты из выгрузки, проверить, что обязательное поле не пусто, найти все цены в дереве категорий. JSONPath понимают Postman, JMeter, Kubernetes (`kubectl -o jsonpath`), тесты на JSON-схемы, ETL-инструменты и библиотеки разбора JSON в большинстве языков. Разбор в этом инструменте — подмножество языка, достаточное, чтобы проверить выражение перед тем, как вставлять его в конфигурацию чужой программы.

Почему в таблице не все найденные значения?

В разметку попадают первые 200 строк: на документе, где выражение находит десятки тысяч значений, таблица такого размера подвесила бы вкладку — не подсчётом, а самой отрисовкой строк. Ограничение касается только показа: в сводке стоит полное число найденных значений, а кнопка «Скопировать результат» отдаёт все строки целиком. Если значение не попало на экран, его можно найти в скопированном тексте, вставив его в таблицу или текстовый редактор.

JSON отправляется на сервер?

Нет. Документ разбирается и запрос выполняется в браузере на JavaScript: ни текст JSON, ни выражение никуда не передаются и не сохраняются. Инструментом можно пользоваться офлайн, а вставлять в него можно выгрузки и ответы API, которые не стоит отдавать во внешний сервис. Обратная сторона в том, что при обновлении вкладки всё введённое пропадёт — результат лучше скопировать сразу.