/tool/json-formatter/ работает дерево, починка, схема
Вставьте ответ API, откройте файл или дайте адрес — форматтер развернёт документ с отступами, а если разбор не пройдёт, покажет строку и колонку, где сломалось, и предложит починить. Дальше по тому же документу работают дерево с путями, выборка по JSONPath, проверка по схеме, сравнение с эталоном и выгрузка в CSV, YAML или XML.
Выражение достаёт из документа только нужное, схема — показывает, где данные разошлись с уговором. Работают по тому же документу, что разобран выше.
Понимает $, точку, ["ключ"], [0], [*], срез [1:3] и две точки — поиск ключа на любой глубине: $..id. Счётчик совпадений обновляется на каждый знак.
Draft-07 в разумном объёме: type, required, enum, const, minimum и maximum (в том числе строгие), minLength и maxLength, pattern, items, properties, patternProperties, additionalProperties, minItems, maxItems, uniqueItems, anyOf, allOf, oneOf, not, $ref внутри самой схемы.
Что нашлось
Выражение не задано
Проверка по схеме
Схема не задана
Обе стороны сначала приводятся к одному виду — ключи по алфавиту, одинаковый отступ, — и только потом сравниваются построчно. Иначе половина «различий» оказалась бы разным порядком ключей.
Второй документ: вчерашний ответ того же метода, выдача с боевого сервера, ожидаемый образец из тестов. Слева — то, что разобрано в первой панели, справа — то, что здесь.
Различия построчно
Эталон не задан
Дайте документ любым из трёх способов: вставьте текст в поле, перетащите файл на пунктирную рамку или на само поле, либо укажите адрес и нажмите «Загрузить». Разбор запускается сразу, кнопку жать не нужно.
Если разбор не прошёл — в замечании будет строка и колонка, а кнопка рядом перенесёт курсор ровно в это место в поле ввода. Указана позиция, где парсер понял, что дальше читать нельзя: сама опечатка обычно на пару символов левее.
Битый JSON из чужого конфига или из лога чините кнопкой «Починить»: она снимает висячие запятые, меняет одинарные кавычки на двойные, закавычивает голые ключи, вырезает комментарии и заменяет NaN, Infinity и undefined на null. Список того, что именно было исправлено, показывается в замечаниях — молча ничего не подменяется.
Вкладка «Дерево» нужна там, где листинг бесполезен: в ответе на три тысячи строк. Узлы сворачиваются, у каждого видно тип и число элементов, а кнопки рядом кладут в буфер путь до узла — в виде $.items[3].id и в виде data["items"][3]["id"].
Вкладки CSV, YAML и XML пересобирают тот же документ в другой формат. CSV получается из массива объектов: столбцы — объединение ключей, вложенное складывается обратно в JSON внутри ячейки. Кнопка «Скачать файлом» отдаёт то, что показано на текущей вкладке.
Выражение JSONPath во второй панели достаёт из документа только нужное: $.items[*].id — все идентификаторы, $..price — все цены на любой глубине. Счётчик показывает, сколько совпало, листинг — что именно.
JSON Schema в той же панели проверяет документ на соответствие уговору. Нарушения выводятся списком с путями: видно не «не сошлось», а «$.items[2].price: ожидалось число, пришла строка».
Сравнение с эталоном в третьей панели показывает, чем два документа отличаются: построчно с пометками и отдельным списком путей. Порядок ключей на результат не влияет — обе стороны сортируются.
Исходные данные — те же, что стоят в полях по умолчанию: их можно пересчитать в уме и убедиться, что инструмент не врёт.
Ключей на верхнем уровне четыре — name, count, tags, meta — плюс два внутри meta: open и path. Итого шесть.
Вложенность: сам объект — первый уровень, массив tags и объект meta — второй. Глубже ничего нет, значит глубина 2.
Каждый элемент массива и каждая пара ключ-значение уходят на свою строку. Скобки массива и объекта тоже занимают по строке.
В дереве это три узла верхнего уровня со значениями и два сворачиваемых: tags — массив на 3 элемента, meta — объект на 2 ключа. Путь до третьего тега — $.tags[2], он же data["tags"][2].
Получается 13 строк: открывающая скобка, name, count, «tags»: [, три тега, закрывающая скобка массива, «meta»: {, open, path и две закрывающие скобки. Ключей 6, глубина 2. Выражение $.tags[*] даст три совпадения, вкладка CSV на таком документе откажется работать — CSV собирается из массива объектов, а здесь корень объект.
Потому что стандарт JSON её не допускает. Висячую запятую разрешают JavaScript, JSON5 и часть сборщиков, но обычный разбор на сервере на ней падает. Форматтер показывает ровно то, что увидит парсер на той стороне. Если чинить надо, а не спорить — нажмите «Починить»: она уберёт запятую и скажет, сколько штук убрала.
Она правит только синтаксис и только за пределами строк: висячие запятые, одинарные и «типографские» кавычки, незакавыченные ключи, комментарии, NaN, Infinity и undefined, лишнюю запятую в конце и защитный префикс )]}' , который некоторые API ставят перед ответом. Значения внутри строк не трогаются. Каждая правка попадает в список замечаний с числом случаев, так что видно, что именно изменилось. Исходный текст при этом заменяется в поле — вернуть его можно обычной отменой в поле ввода.
В листинге, дереве, выборке и выгрузках — нет: числа переписываются ровно теми знаками, какими пришли, без превращения в дробное число двойной точности. Идентификатор из девятнадцати цифр останется прежним. Отдельным замечанием выводятся все числа за пределами безопасного целого — с путями, чтобы было видно, какое поле нельзя отдавать в JavaScript как число. Сравнение чисел в схеме идёт уже через обычное число, и на девятнадцати цифрах оно приблизительно.
Разбор пройдёт, обе пары останутся в результате, а в замечаниях появится путь до каждого повтора — вида $.items[3].id, а не просто «id». Стандарт поведение при повторе не определяет: один парсер возьмёт первое значение, другой последнее. Поэтому повтор — почти всегда ошибка сборки данных.
Вставленный текст, открытый файл, схема и эталон разбираются в браузере и никуда не отправляются. Единственное исключение — кнопка «Загрузить» рядом с полем адреса: она делает запрос к указанному вами адресу. Черновик и настройки хранятся в localStorage этого браузера, кнопка «Сбросить» их стирает. Ссылка на результат тоже никуда не ходит: документ сжимается и кладётся в хэш адреса, а хэш на сервер не передаётся.
Браузер не даёт странице читать ответ чужого сервера, если тот не разрешил это заголовком Access-Control-Allow-Origin. Публичные API его обычно ставят, внутренние — почти никогда. Когда браузер закрывает ответ, инструмент пробует то же самое через наш сервер, и если действие на нём ещё не поднято, честно об этом говорит. Рабочий обход — сохранить ответ файлом и открыть файл.
Предел — 10 МБ. Разбор идёт в отдельном потоке, поэтому вкладка не замирает, а полоса под кнопками показывает, сколько прочитано. В листинге при этом показывается начало результата, а не весь он целиком: полмиллиона строк ни один браузер не нарисует. Целиком результат забирается кнопками «Скопировать» и «Скачать файлом».
В файле JSON Lines на каждой строке лежит отдельный документ, а запятых и общих скобок между ними нет. Так пишут логи и выгрузки: файл можно дописывать в конец и читать по строке, не держа в памяти целиком. В этом режиме форматтер разбирает каждую строку отдельно и называет номер той, которая сломалась. Для дерева, выборки, схемы и выгрузок записи собираются в один массив — так CSV из лога получается сразу.
CSV — плоская таблица, а JSON — дерево. Собрать из дерева таблицу можно только тогда, когда корень (или записи JSON Lines) — массив объектов: тогда столбцы это объединение ключей, а строки — объекты. Вложенные объекты и массивы кладутся в ячейку тем же JSON: это честнее, чем терять их или разворачивать в сотню столбцов.