Все статьи
Форматы данных

JSONPath: извлечение данных из JSON

Синтаксис JSONPath, запросы к JSON, примеры использования, отличие от jq, практические задачи.

6 февраля 2025
9 мин чтения
ConvertHub
#jsonpath#jq#запросы

Введение

Современные API возвращают вложенные JSON-структуры на десятки уровней: объекты внутри массивов внутри объектов. Когда нужно вытащить конкретное поле или коллекцию значений, навигация вручную через точку и квадратные скобки становится утомительной. На помощь приходит JSONPath — язык запросов к JSON, аналог XPath для XML. С его помощью можно извлекать данные по шаблонам, фильтровать массивы и обходить произвольные деревья. В этой статье разберём синтаксис JSONPath, примеры запросов и частые сценарии использования.

Что такое JSONPath

JSONPath — это язык запросов, созданный Штефаном Гёсснером в 2007 году. Он позволяет обращаться к элементам JSON через путь, похожий на путь файловой системы, но с поддержкой wildcards, фильтров и срезов массивов. JSONPath реализован во множестве библиотек для JavaScript, Python, Java, Go, PHP и других языков. Стандартизация формата была завершена в IETF RFC 9535 в 2024 году, что устранило диалектные различия между реализациями.

Пример JSON, на котором будем тренироваться:

{
  "store": {
    "books": [
      { "title": "Война и мир", "author": "Толстой", "price": 1200 },
      { "title": "Анна Каренина", "author": "Толстой", "price": 950 },
      { "title": "Идиот", "author": "Достоевский", "price": 1100, "isbn": "978-5-389" }
    ],
    "magazines": [
      { "title": "Наука и жизнь", "issue": 12 }
    ]
  }
}

Базовый синтаксис

JSONPath использует два стиля записи: dot-notation($.store.books[0].title) и bracket-notation($['store']['books'][0]['title']). Первый компактнее, второй позволяет использовать ключи со спецсимволами. Символ $ обозначает корень JSON.

СимволЗначениеПример
$Корень документа$
.Дочерний узел$.store
..Рекурсивный спуск$..author
*Wildcard — любой элемент$.store.*
[n]Индекс массива$..books[0]
[a:b]Срез массива$..books[0:2]
[?expr]Фильтр$..books[?@.price<1000]

Примеры запросов

Получение всех заголовков книг

$..books[*].title

// Результат:
// ["Война и мир", "Анна Каренина", "Идиот"]

Все авторы (рекурсивный поиск)

$..author

// Результат:
// ["Толстой", "Толстой", "Достоевский"]

Две точки .. означают «искать на любой глубине». Это удобно, когда структура может меняться, а поле нужно найти в любом месте.

Фильтрация по условию

$..books[?@.price < 1000].title

// Результат:
// ["Анна Каренина"]

Символ @ обозначает текущий элемент массива. В фильтрах поддерживаются операторы сравнения (==, !=, <,>), логические (&&, ||) и функции (length(), contains()).

Срезы массива

$..books[0:2]   // первые две книги
$..books[-1]    // последняя книга
$..books[1:]    // все книги со второй

Срезы работают как в Python: [start:end:step]. Отрицательные индексы отсчитываются с конца массива.

Условие на существование поля

$..books[?@.isbn].title

// Результат:
// ["Идиот"]

Этот запрос возвращает только те книги, у которых есть поле isbn. Полезно для фильтрации объектов с необязательными полями.

Фильтры и выражения

Фильтры — самая мощная часть JSONPath. Внутри квадратных скобок с вопросительным знаком можно писать выражения любой сложности:

  • [?@.price > 1000 && @.author == 'Толстой'] — книги Толстого дороже 1000 рублей.
  • [?@.title contains 'Анна'] — книги с «Анна» в названии (не во всех реализациях).
  • [?@.tags.length() > 3] — объекты с более чем тремя тегами.
  • [?(@.price + @.tax) < 2000] — арифметика в фильтрах.

Синтаксис фильтров различается между реализациями: старые версии не поддерживаютcontains как оператор, в новых появился in иmatches. Стандарт RFC 9535 унифицировал эти возможности.

JSONPath vs jq

Часто JSONPath сравнивают с jq — популярной утилитой командной строки для запросов к JSON. У них разная философия: JSONPath — компактный язык путей, встроенный в библиотеки; jq — полноценный функциональный язык с переменными, функциями и конвейерами.

КритерийJSONPathjq
Сложность обученияНизкаяСредняя
ВыразительностьСредняяВысокая
Встроен в библиотекиДаНет (CLI)
Трансформация данныхОграниченнаяПолная
Фильтры и условияБазовыеБогатые
ПрименениеВеб-приложения, APIСкрипты, CLI

Для большинства задач извлечения данных JSONPath достаточно. Если нужно делать сложную трансформацию — группировку, агрегацию, маппинг — jq удобнее.

Применение JSONPath

  • Тестирование API — в Postman и REST Assured JSONPath используется для проверок ответов. Например, проверить, что $.data[0].id равен ожидаемому значению.
  • Конфигурация observability — Datadog, Splunk, Logstash применяют JSONPath для извлечения метрик из логов в JSON-формате.
  • JSON-логирование — при анализе структурированных логов часто нужно вытащить поле по пути, не зная заранее глубину вложенности.
  • Мониторинг событий — вебхуки и системы оповещения используют JSONPath для извлечения значений из payload.
  • Динамические правила доступа — в некоторых IAM-системах политики описываются через JSONPath к полям запроса.

Инструменты для работы с JSONPath

Онлайн-инструмент

Для тестирования запросов используйте нашJSONPath Finder. Вставляете JSON, вводите путь — инструмент подсвечивает совпадающие элементы прямо в дереве. Это удобно для отладки сложных фильтров и обучения синтаксису.

Библиотеки

  • JavaScriptjsonpath-plus (полная поддержка стандарта), jsonpath (старый).
  • Pythonjsonpath-ng, jsonpath2.
  • JavaJsonPath от Jayway.
  • Gogithub.com/PaesslerAG/jsonpath.
  • .NETNewtonsoft.Json с методом SelectToken.

Пример в JavaScript

import { JSONPath } from 'jsonpath-plus';

const data = { store: { books: [/* ... */] } };

const titles = JSONPath({ path: '$..books[?@.price < 1000].title', json: data });
console.log(titles); // ["Анна Каренина"]

Производительность и ограничения

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

JSONPath не предназначен для модификации данных — только для извлечения. Если нужно изменить поле по пути, используйте специализированные библиотеки вродеimmutable-json-patch или реализуйте обход вручную.

Лучшие практики

  • Предпочитайте $.field вместо $..field, когда знаете структуру — это быстрее.
  • Используйте фильтры с осторожностью: чем сложнее выражение, тем медленнее запрос.
  • Тестируйте запросы на реальных данных перед использованием в продакшне.
  • Документируйте неочевидные запросы — JSONPath читается хуже, чем обычный код.
  • Помните, что разные реализации могут поддерживать разный набор функций.
  • Для больших JSON используйте стриминговые парсеры, а не загружайте весь документ в память.

Связанные инструменты

После извлечения данных через JSONPath их часто нужно отформатировать или преобразовать. Для этого подходят JSON форматтердля красивого отображения, JSON в CSV для табличного экспорта и JSON в TypeScript для генерации типов. Если данные пришли в минифицированном виде, сначала применитеформатирование, а потом — JSONPath.

Заключение

JSONPath — компактный и выразительный язык для извлечения данных из JSON. Он незаменим в тестировании API, анализе логов и автоматизации. Базовый синтаксис осваивается за час, а продвинутые фильтры покрывают большинство сценариев. Для экспериментов используйте JSONPath Finder от ConvertHub — он работает локально и подсвечивает совпадения в дереве. Если нужно больше выразительности — присмотритесь к jq, но для типичных задач JSONPath хватает с запасом.

Попробуйте эти инструменты

Похожие статьи