Инструменты разработчика · JSON форматировщик и валидатор
Вся грамматика JSON на одной странице: шесть типов значений, два контейнера
· Фон
JSON стандарты проверка
Вся грамматика JSON умещается на одной странице, и знание ее наизусть делает каждую ошибку валидатора очевидной. В этом посте рассматриваются шесть типов значений, два контейнера и несколько правил, которые сбивают людей с толку.
Каждая ошибка, которую вы когда-либо видели, происходит с одной страницы.
Каждая синтаксическая ошибка — это нарушение ожидания в компактной грамматике. После открытия объекта анализатор ожидает имя члена в кавычках или закрывающую скобку; после имени ожидается двоеточие; после значения ожидается запятая или конец контейнера. Считывание ошибки как неудачного перехода более полезно, чем рассмотрение сообщаемого символа как загадочного.
ToolAcre принимает стандартные значения JSON и пробелы, а затем применяет два практических ограничения ввода. Текст длиной более 8,000,000 символов отклоняется перед синтаксическим анализом, а вложение сканера за пределами контейнеров 512 отклоняется, а не проходится бесконечно. Это границы продукта, а не новые типы JSON. Внутри них диагностика определяет первую точку, в которой поток токенов больше не может удовлетворять грамматике.
Шесть значений — объект, массив, строка, число, true/false и null, а также тот факт, что больше ничего нет.
Значение JSON — это объект, массив, строка, число, логическое значение или значение NULL. Объекты и массивы могут содержать любой из шести, включая дополнительные контейнеры. Буквальное написание — это `true`, `false` и `null`; капитализация не является гибкой. Такие токены, как `True`, `None`, `undefined`, `NaN` и `Infinity`, находятся за пределами строгого JSON, даже если некоторые из них распознаются другим языком.
Этот краткий список делает классификацию полезным методом отладки. В `{"reading": NaN}` двоеточие правильно вводит значение, но `N` не может начинать какое-либо разрешенное значение. Замените его только после того, как решите, что должны означать данные, например `null` или статус в кавычках. Инструмент синтаксиса может отклонить токен; он не может выбрать замену приложения или решить, принадлежит ли ему поле.
Объекты и массивы — члены, разделенные запятыми, двоеточие и почему RFC 8259 оставляет порядок и дублирующиеся имена реализациям
Объекты содержат элементы name/value, разделенные запятыми. Каждое имя представляет собой строку в двойных кавычках, за которой следует двоеточие и значение. Массивы содержат значения, разделенные запятыми, без имен и двоеточий. Пустые контейнеры `{}` и `[]` допустимы, но запятая не может начинаться, заканчиваться или появляться дважды. Сопоставление каждого разделителя с его контейнером быстро выявляет множество очевидных «неожиданных ошибок токена».
Ожидается, что имена объектов будут уникальными, однако этот валидатор не отклоняет дублирующиеся написания. `{"port": 80, "port": 443}` анализирует, а `JSON.parse` сохраняет более позднее значение. Затем при форматировании создается только этот сохранившийся элемент, поэтому более ранний текст невозможно восстановить из результата. Позиции массива ведут себя по-разному: каждый элемент остается присутствующим, а его порядок является частью значения.
Строки и числа точно
В строках используются двойные кавычки. Обратная косая черта может представлять собой кавычку, обратную косую черту, косую черту, `b`, `f`, `n`, `r`, `t` или четырехзначный escape-код Юникода; необработанные управляющие символы запрещены. Одинарные кавычки — это обычные недопустимые токены вне строки. Эти правила объясняют, почему скопированные литералы JavaScript и вставленный многострочный текст могут выглядеть читаемыми, хотя и не проходят строгую проверку JSON.
Число может иметь знак минус, целую часть, необязательную дробь и необязательный показатель степени. Он не может начинаться с `+`, использовать шестнадцатеричную запись, содержать нуль перед другой цифрой или писать неконечное значение. `-0.25e+2` действителен; `01`, `.5`, `2.` и `Infinity` — нет. При синтаксическом анализе проверяется грамматика, а не то, может ли JavaScript точно сохранить каждую цифру.
Пробелы и верхний уровень
Вне строк пробелы JSON ограничены пробелом, горизонтальной табуляцией, переводом строки и возвратом каретки. Неразрывный пробел, скопированный с веб-страницы, не является взаимозаменяемым с обычным пробелом. Форматирование может свободно выбирать разрешенные пробелы вокруг токенов, но оно должно сохранять пробелы, принадлежащие внутри строки в кавычках, поскольку эти символы являются данными.
Полный документ может представлять собой любое отдельное значение JSON, а не только объект или массив. `42`, `false` и `"ready"` являются допустимыми текстами верхнего уровня. Запрещено второе значение после первого: `42 43` — это два документа, а не один. Это различие объясняет, почему JSON с разделителем новой строки требует обработки по записи, а не одного обычного анализа всего файла.
Рабочий пример: разбор небольшого документа вручную
Возьмите `{"order": [17, null, {"paid": true}], "note": "ship скоро"}`. The root object begins a member named `order`; its value is an array containing a number, null and another object. A comma then introduces `note`, значение которого представляет собой строку с экранированным символом новой строки. Каждое двоеточие, запятая и закрывающий разделитель имеют одну грамматическую роль.
Теперь удалите кавычки перед `paid`. После вложенной скобки анализатор ожидает закрывающую скобку или имя в кавычках, поэтому на `p` происходит сбой. Альтернативно добавьте запятую после `true`; синтаксический анализатор принимает запятую, а затем терпит неудачу на `}`, поскольку за ней должен следовать другой член. Прогнозирование этих позиций вручную превращает проверку в подтверждение и препятствует случайному редактированию знаков препинания.
Что это не распространяется
Грамматика не имеет даты, десятичных чисел, двоичных чисел, UUID или типа длительности. Приложения обычно представляют эти понятия в виде строк или чисел и налагают соглашения отдельно. Временная метка может быть совершенно допустимой строкой JSON, но содержать невозможную дату. Аналогично, синтаксически допустимый объект может опускать обязательные свойства или использовать неправильные единицы измерения, не нарушая при этом ни одного правила синтаксического анализа.
ToolAcre не выполняет проверки схемы, проверку домена или канонизацию. Он также не переосмысливает функции JSON5 или JSONC, такие как комментарии и конечные запятые. Его задача уже: принять один строгий текст JSON в пределах продукта, отформатировать разобранное значение и выявить синтаксические ошибки. Оставьте последующие вопросы о форме и значении на уровне проверки приложения-потребителя.
Вывод: запоминайте грамматику, доверяйте позиции
Надежный контрольный список короткий: шесть категорий значений, имена объектов в кавычках, только запятые между элементами, только двоеточия между именами и значениями, строгое экранирование строк, строгое написание чисел, четыре пробельных символа и ровно одно значение верхнего уровня. Если документ терпит неудачу, определите, что допускает грамматика непосредственно перед сообщаемой позицией, и сравните это ожидание с фактически присутствующим символом.
Доверяйте позиции первой невозможной точке, а не персонажу, которого нужно удалить. Закрывающая скобка может быть выделена, поскольку предыдущая запятая обещала другой член; невинная буква может быть выделена, потому что ее вступительная цитата отсутствует. Устраните причину, повторно запустите проверку и повторите. В случае слишком большого или слишком глубокого ввода устраните границу продукта в 8-миллион символов или 512-глубину, прежде чем диагностика синтаксиса сможет помочь.