Вложенность и массивы: путь к значению, JSONPath
↑ 1.4 JSON, XML и другие форматы · ← Предыдущая · → Следующая
Зачем это аналитику и PM
В баге пишут «цена не та», а в ответе цен две: у заказа и у позиции. Путь к значению фиксирует, какую именно. Иначе разработчик правит не то поле.
План темы
- как обратиться к полю
- фильтры по массиву
- инструменты (jq, онлайн-просмотрщики, расширения браузера)
Объяснение
Путь к значению — цепочка от корня документа к одному месту: какие ключи открыть и какой элемент списка взять. Пока путь не записан, короткое имя status может найтись и у заказа, и у оплаты, и у доставки.
Как адрес в шкафу. Комната — корень. Полка — ключ. Папка на полке — номер в списке. Лист в папке — снова ключ. «Третий лист на второй полке» не путают с «третьей полкой».
Как обратиться
В разговоре путь читают словами: «корень, объект order, массив items, первый элемент, ключ sku». В тексте удобна точечная запись order.items[0].sku. Номер с нуля. Если items нет или он короче, пути нет: это не пустая строка, а отсутствующее место. В задаче так и пишут.
JSONPath — отдельный язык путей. Здесь имеется в виду общий минимум, который узнают большинство инструментов: $ — корень, точка и имя ключа, индекс в квадратных скобках, * — все элементы списка.
| Путь | Что берёт в примере ниже |
|---|---|
$.order.id | строку 1042 |
$.order.items[0].sku | MUG-1 |
$.order.items[*].sku | артикулы всех позиций |
Фильтры вида «только позиции, где количество больше одного» в JSONPath есть, но запись зависит от диалекта. Старые инструменты и текст RFC 9535 расходятся в скобках и в знаке сравнения. В этой заметке фильтр не приводится как готовый рецепт. Если он нужен в задаче, путь копируют из того инструмента, которым пользуется команда, и один раз проверяют на примере.
Инструменты
jq — программа в терминале, это не JSONPath. Тот же артикул в jq часто пишут .order.items[0].sku, без знака $. Все артикулы — .order.items[].sku. Путаница двух языков даёт путь, который «почти такой» и ничего не находит.
В браузере длинный ответ смотрят во вкладке сети: многие панели умеют свернуть объект. Онлайн-просмотрщик и расширение ставят только на учебные и тестовые тела. Боевой ответ с персональными данными в чужой сайт не вставляют. Имя конкретного расширения здесь не рекомендуется: их много, и набор меняется.
Примеры
Схема заказа. По ней сверены пути из таблицы.
{
"order": {
"id": "1042",
"items": [
{"sku": "MUG-1", "qty": 2},
{"sku": "CUP-2", "qty": 1}
]
}
}$.order.items[1].sku — это CUP-2, вторая позиция, не первая. $.order.items[*].qty — числа 2 и 1, не одно поле «количество заказа». Отдельного ключа qty у корня нет.
Фрагмент для jq, если файл лежит в order.json:
jq '.order.items[].sku' order.jsonЭто иллюстрация синтаксиса jq, не обещание, что утилита уже стоит на машине. Есть ли она у вас, смотрите в теме про утилиты командной строки.
Нюансы и подводные камни
- Индекс
[1]— второй элемент. В речи «позиция 1» часто значит первую. В задаче пишут и слова, и индекс. [*]возвращает список. Поле экрана, которое ждёт одну строку, так не заполняют без правила «что делать, если позиций несколько».- Одинаковые ключи на разной глубине — норма. Запрещено только молчаливое «возьмите status».
Практика
На схеме заказа выше выпишите путь к артикулу второй позиции и путь ко всем количествам. Рядом пометьте, это слова, точечная запись или jq.
Ожидаемый результат: вторая позиция указана индексом 1, не 2. Количества взяты из каждого элемента items, не из корня. Для фильтра «qty больше 1» либо стоит вопрос «каким инструментом пользуемся», либо вставлен путь, который вы сами прогнали на этом JSON.
Вопросы с ответами
Зачем путь, если имя поля и так видно?
Одно имя встречается на нескольких уровнях. Путь говорит, какой уровень имеется в виду, и какой элемент списка взят. [!question]- JSONPath и jq — одно и то же?
Нет. Общая идея похожа, знаки разные.
$и[*]— примета JSONPath.jqчаще начинает с точки и пишет[]без звёздочки. В задаче называют язык. [!question]- Почему в заметке нет готового фильтра массива?Запись фильтра зависит от диалекта. Общий минимум — ключ, индекс и «все элементы». Фильтр копируют из своего инструмента и проверяют на примере.