В конце входного json файла были обнаружены лишние символы
Строка JSON должна быть заключена в двойные кавычки, согласно спецификациям , поэтому вам не нужно экранировать '
. Если вам нужно использовать специальный символ в строке JSON, вы можете избежать его, используя символ \ .
См. этот список специальных символов, используемых в JSON:
Однако, даже если это полностью противоречит спецификации, автор может использовать \' .
Это плохо , потому что:
- Это противоречит спецификации
- Это больше не допустимая строка JSON
Но это работает, как вы хотите этого или нет.
Для новых читателей всегда используйте двойные кавычки для строк json.
Я потрясен наличием дезинформации с высоким голосом по такому часто обсуждаемому вопросу по основной теме.
Строки JSON нельзя заключать в одинарные кавычки . Различные версии спецификации ( оригинал Дугласа Крокфорда, версия ECMA и версия IETF ) все утверждают, что строки должны быть заключены в двойные кавычки. Это не теоретический вопрос и не вопрос мнения, как это принято в настоящее время; любой анализатор JSON в реальном мире выдаст ошибку, если вы попытаетесь проанализировать строку в одинарных кавычках.
Версия Крокфорда и ECMA даже отображает определение строки, используя красивую картинку, которая должна четко и ясно прояснить ситуацию:
На красивой картинке также перечислены все допустимые escape-последовательности в строке JSON:
-
\" литий> \\ литий> \/ литий> \b литий> \f литий> \n литий> \r литий> \t литий>
- \u , за которым следуют четыре шестнадцатеричные цифры
Обратите внимание, что вопреки бессмыслице в некоторых других ответах здесь, \' никогда не является допустимой escape-последовательностью в строке JSON. Так не должно быть, потому что строки JSON всегда заключаются в двойные кавычки.
Наконец, вам обычно не нужно думать о экранировании символов самостоятельно при программном создании JSON (хотя, конечно, вы будете это делать при ручном редактировании, скажем, файла конфигурации на основе JSON). Вместо этого сформируйте структуру данных, которую вы хотите кодировать, используя любые типы карт, массивов, строк, чисел, логических и нулевых значений, которые есть у вашего языка, а затем закодируйте ее в JSON с помощью функции кодирования JSON. Такая функция, вероятно, встроена в любой используемый вами язык, например, в JavaScript. JSON.stringify , PHP json_encode или json.dumps . Если вы используете язык, который не имеет такой встроенной функциональности, вы можете найти библиотеку синтаксического анализа и кодирования JSON для использования. Если вы просто используете язык или библиотечные функции для преобразования вещей в JSON и обратно, вам даже не нужно знать правила экранирования JSON. Это то, что должен был сделать неверный задающий вопрос.
Все говорят о том, как избежать ' в ' строковый литерал в кавычках. Здесь есть гораздо более серьезная проблема: строковые литералы в одинарных кавычках недопустимы в формате JSON . JSON основан на JavaScript, но это не одно и то же. Если вы пишете литерал объекта внутри кода JavaScript, хорошо; если вам действительно нужен JSON, вам нужно использовать " .
С помощью строк в двойных кавычках вам не нужно экранировать ' . (И если вы хотите, чтобы в строке был буквальный " , вы бы использовали \" )
Может быть, я слишком опоздал на вечеринку, но это будет анализировать /избегать одинарной кавычки (не хочу вступать в битву при разборе против побега) ..
Я думаю, что мы все согласны с тем, что одиночные кавычки не настоящие. Как бы то ни было, нам все еще нужно решить вопрос о том, чтобы уйти "внутри строки json в двойных кавычках, в отсутствие библиотек, чтобы сделать это для нас.
Замена каждого "на \" НЕ ДОСТАТОЧНА: Пользователь может ввести ввод: \ и синтаксический анализ, опять же, не удается (подумайте почему).
Вместо этого сначала замените каждый \ на \ (двойной обратный слеш). Только после этого заменяйте каждое «на \» (с обратной косой чертой следует «).
Ответ на прямой вопрос:
В целях безопасности замените необходимый символ на \ u + 4-значный-шестнадцатеричное значение
Пример: Если вы хотите избежать апострофа, замените на \ u0027
D'Amico становится D'Amico
экранирование одинарных кавычек действительно только в одинарных кавычках
двойные кавычки действительны только в двойных кавычках json
Цифровые значения
Последняя типовая ошибка связана с кодированием числовых значений.
Уже лучше. Но как видим «3.0» превратилось в 3, что в большинстве случаев будет интерпретировано как int. Используем еще один флаг JSON_PRESERVE_ZERO_FRACTION для корректного преобразования в float:
Прошу также обратить внимание на следующий фрагмент кода, что иллюстрирует ряд возможных проблем с json_encode и числовыми значениями:
Спасибо за прочтение.
Буду рад увидеть в комментариях описание проблем, с которыми вы сталкивались, что не были упомянуты в статье
Формат ваших данных не соответствует стандарту JSON. Ключ должен быть строкой и 1с тут ни при чем.
Ожидается, что другие стандарты будут относиться к этому, строго придерживаясь текстового формата JSON, в то время как накладывая ограничения на различные детали кодирования. Такие стандарты могут потребовать определенного поведения. JSON сам не указывает никакого поведения.
Далее в стандарте (стр. 2) спецификация объекта JSON:
Структура объекта представлена в виде пары фигурных фигурных скобок, окружающих нулевые или более пары имен/значений. Имя - это строка. Каждому имени соответствует один идентификатор двоеточия, отделяющий имя от значения. Один токен разделяет значение из следующего имени.
(6) Формат данных соответствует стандарту JSON. Имя - это строка. А строка в JSON - это символы, заключенные в кавычки. Отсутствует ограничение, что первый символ строки должен быть буквой. Структура представлена пятью парами имен/значений. Все имена - это строки. И 1С прочитает этот JSON путем Ответ=ПрочитатьJSON(ЧтениеJSON, Истина);
При чтении создается структура. В структуре нельзя что бы ключи были числа. Читайте в соответствие.
Ответ=ПрочитатьJSON(ЧтениеJSON, Истина);
request4t; ulen; Prad2002; farraf; user845559; user712426; daab; Rustam10; adhocprog; timurhv; Andreyyy; + 11 – Ответить
Что-то мне подсказывает, что такие обозначения свойств JSON объекта не приветствуются в 1С.
Как, спрашивается, обращаться к ним после парсинга в структуру? "СтруктураДанных.800"?
Вот оно на ранних подступах и выдает ошибку.
А то, что ругается на последнюю запись - это нормально. JSON парсится с хвоста.
Глобальный контекст.ПрочитатьJSON (Global context.ReadJSON)
Глобальный контекст (Global context)
ПрочитатьJSON (ReadJSON)
Синтаксис:
(3) После чтения в соответствие к ним нужно обращаться как к соответствию - Ответ["distribution"]["0"]. Либо Ответ.Получить("distribution").Получить("200")
Ошибку выдает, потому что идет попытка прочитать в структуру, а такой JSON можно прочитать только в соответствие.
FOR JSON PATH или FOR JSON AUTO?
Вопрос. Мне нужно создать текстовый результат JSON из простого SQL-запроса для одной таблицы. Выходные данные для FOR JSON PATH и FOR JSON AUTO совпадают. Какой из этих вариантов следует использовать?
Ответ. Используйте FOR JSON PATH. Несмотря на отсутствие различий в выходных данных JSON, режим AUTO применяет дополнительную логику, определяющую потребность во вложенных столбцах. Рассматривайте PATH как параметр по умолчанию.
Кодировка текстовых значений
Кириллица и другие знаки в UTF8
Второй тип распространённых проблем с json_encode это проблемы с кодировкой. Часто текстовые значения которые нужно кодировать в json имеют в себе символы в UTF8 (в том числе кириллица) в результате эти символы будут представлены в виде кодов:
Отображение таких символов лечится очень просто — добавлением флага JSON_UNESCAPED_UNICODE вторым аргументом к функции json_encode:
Доступ к полям
Проблема заключается в том что json_encode имеет доступ только к публичным полям объекта. Например если у вас есть класс
то результатом выполнения следующего кода будет:
как видно в результирующий json были включены только публичные поля.
Что же делать если нужны все поля?
Решение
Для php < 5.4:
нам необходимо будет реализовать в классе метод который будет возвращать готовый json. Т.к. внутри класса есть доступ ко всем полям можно сформировать правильное представление объекта для json_encode
Для получение json-a c объекта теперь нужно пользоваться методом toJson, а не прямым применением json_encode к объекту
Для php >= 5.4:
достаточно будет реализовать интерфейс JsonSerializable для нашего класса, что подразумевает добавление метода jsonSerialize который будет возвращать структуру представляющую объект для json_encode
Теперь мы можем использовать json_encode как и раньше
Почему не стоит использовать подход с toJson методом?
Многие наверно заметили что подход с созданием метода возвращающего json может быть использован и в версиях php >= 5.4. Так почему же не воспользоваться им? Все дело в том что ваш класс может быть использован как часть иной структуры данных
и результат уже будет совсем другой.
Также класс может использоваться другими программистами, для которых такой тип получение json-а с объекта может быть не совсем очевиден.
Что если у меня очень много полей в класcе?
В таком случае можно воспользоваться функцией get_object_vars
А если нужно private-поля, из класса, который нет возможности редактировать?
Может получиться ситуация когда нужно получить private поля (именно private, т.к. доступ к protected полям можно получить через наследование) в json-е. В таком случае необходимо будет воспользоваться рефлексией:
Дополнительные сведения о JSON в SQL Server и базе данных SQL Azure
Ключи ссылки, содержащие символы, отличные от буквенно-цифровых, в тексте JSON
Вопрос. Ключи в тексте JSON содержат символы, отличные от буквенно-цифровых. Как можно сослаться на эти свойства?
Ответ. Необходимо заключить их в кавычки в путях JSON. Например, JSON_VALUE(@json, '$."$info"."First Name".value') .
Популярные теги
Я сгенерировал JSON и пытаюсь превратить его в объект в JavaScript. Я все время получаю ошибки. Вот что у меня есть:
Это дает мне ошибку:
Когда я вынимаю \n после, sometext ошибка исчезает в обоих случаях. Кажется, я не могу понять, почему все \n делает eval и JSON.parse терпит неудачу.
Вот чего вы хотите:
Вам нужно экранировать \ строку (превратив ее в двойную \ ), иначе она станет новой строкой в источнике JSON, а не данными JSON.
Это, конечно, правильно, но я хотел бы добавить причину, по которой это необходимо: спецификация JSON на ietf.org/rfc/rfc4627.txt содержит это предложение в разделе 2.5: «Все символы Unicode могут быть помещены в кавычки, за исключением символов, которые необходимо экранировать: кавычки, обратная косая черта и управляющие символы (от U + 0000 до U + 001F) ". Поскольку новая строка является управляющим символом, ее необходимо экранировать.
Согласно www.json.org JSON принимает управляющую последовательность "\ n" в строках - и если вы попробуете JSON.parse (['"a \\ na"']) [1] .charCodeAt (); это покажет 10 - что было "перевод строки" в последний раз, когда я проверял. --- Кстати: хватит кричать!
+ 1. У меня возникли проблемы с пониманием кодировки JSON, но "станет новой строкой в источнике JSON, а не данными JSON" ясно дало мне понять.
Люди могут подумать, что экранирование \n - это экранирование \ (не знаю, как заключить в кавычки \ in line . ) как \\ plus n . Фактически, \n это управляющий символ, обозначаемый \u000A как точка Юникода. "\n" точно так же, как "\u000A" . Итак, побег \n - это побег \u000A . Его экранированная форма есть \n , и мы должны написать \ as \\ в строке Javascript, поэтому "\\n" это правильный ответ. Для powershell ` вместо \ используется escape-символ. Символ новой строки обозначается как `n . ConvertTo-Json "`n" попадет "\n" , а ConvertFrom-Json ‘"Line 1\nLine 2"’ попадет Line 1 и Line 2 в две строчки.
Вам понадобится функция, которая заменяет \n на, \\n если data это не строковый литерал.
Результат dataObj будет
вам нужно экранировать escape-символы (т.е. .replace("\\n", "\\\\n") ), и я бы также предложил использовать регулярное выражение, чтобы разрешить замену нескольких экземпляров (т.е. .replace(/\n/g, "\\\\n") )
зачем вам экранировать escape-символы? Я имею в виду что-то вроде .replace("\n", "\\n") должно работать нормально !! Например, var test = [<"description":"Some description about the product. This can be multi-line text.">]; console.log(JSON.parse(test.replace(/\n/g, "\\n"))); объект отлично выводится на консоль браузера как [<"description":"Some description about the product.\nThis can be multi-line text.">]"description":"Some>
Кстати, в приведенном выше комментарии исходная строка JSON имеет новую строку, которая удаляется средством форматирования комментариев stackoverflow. Вы можете видеть, что окончательный вывод после замены должен вставить символ новой строки \n в значение.
A string is a sequence of Unicode code points wrapped with quotation marks ( U+0022 ). All characters may be placed within the quotation marks except for the characters that must be escaped: quotation mark ( U+0022 ), reverse solidus ( U+005C ), and the control characters U+0000 to U+001F . There are two-character escape sequence representations of some characters.
Таким образом, вы не можете передавать 0x0A или 0x0C кодировать напрямую. Запрещено! Спецификация предлагает использовать escape-последовательности для некоторых четко определенных кодов от U+0000 до U+001F :
- \f представляет собой символ подачи формы ( U+000C ).
- \n представляет символ перевода строки ( U+000A ).
Поскольку большинство языков программирования используют \ для цитирования, вам следует избегать синтаксиса escape (двойной escape - один раз для языка / платформы, один раз для самого JSON):
Здесь приведены ответы на некоторые распространенные вопросы о встроенной поддержке JSON в SQL Server.
Другие вопросы
Предотвращение появления дважды экранированного JSON в выходных данных FOR JSON
Вопрос. Имеется текст JSON, хранящийся в столбце таблицы. Я хочу включить его в выходные данные FOR JSON. При этом FOR JSON экранирует все символы в JSON, поэтому я получаю строку JSON вместо вложенного объекта, как показано в следующем примере.
Этот запрос получает следующие выходные данные.
Как можно избежать этого? Я хочу, чтобы возвращался в виде объекта JSON, а не escape-текста.
Ответ. JSON, хранящийся в столбце текста или литерале, обрабатывается как обычный текст. В связи с этим он заключается в двойные кавычки и экранируется. Если вам нужно возвратить неэкранированный объект JSON, следует передать столбец JSON как аргумент функции JSON_QUERY, как показано в следующем примере.
JSON_QUERY без второго необязательного параметра возвращает в качестве результата только первый аргумент. Так как JSON_QUERY всегда возвращает правильный объект JSON, FOR JSON определяет, что экранировать этот результат не нужно.
Возвращение вложенного подчиненного объекта JSON из текста JSON с помощью OPENJSON
Вопрос. Не удается открыть массив cоставных объектов JSON, содержащий скалярные значения, объекты и массивы, с помощью OPENJSON с явной схемой. Когда я ссылаюсь на ключ в предложении WITH, возвращаются только скалярные значения. Объекты и массивы возвращаются в виде значений NULL. Как извлекать объекты или массивы в качестве объектов JSON?
Ответ. Если требуется возвратить объект или массив в виде столбца, используйте параметр AS JSON в определении столбца, как показано в следующем примере.
Похожие вопросы
Символы в других кодировках
Функция json_encode воспринимает строковые значения как строки в UTF8, что может вызвать ошибку, если кодировка другая. Рассмотрим маленький кусочек кода (данный пример кода максимально упрощен для демонстрации проблемной ситуации)
На первый взгляд ничего не предвещает проблем, да и что здесь может пойти не так? Я тоже так думал. В подавляющем большинстве случаев все будет работать, и по этой причине поиск проблемы занял у меня несколько больше времени, когда я впервые столкнулся с тем что результатом json_encode было false.
Для воссоздания такой ситуации предположим что p=%EF%F2%E8%F6%E0 (на пример: localhost?=%EF%F2%E8%F6%E0 ).
*Переменные в суперглобальных массивах $_GET и $_REQUEST уже декодированы.
Как можно увидеть из ошибки: проблема с кодировкой переданной строки (это не UTF8). Решение проблемы очевидное — привести значение в UTF8
JSON, созданная с помощью предложения WITHOUT_ARRAY_WRAPPER, экранируется в выходных данных FOR JSON
Вопрос. Я пытаюсь отформатировать выражение столбца с помощью FOR JSON и параметра WITHOUT_ARRAY_WRAPPER.
Похоже, что текст, возвращаемый запросом FOR JSON, экранируется как обычный текст. Это происходит только в том случае, если указан WITHOUT_ARRAY_WRAPPER. Почему он не рассматривается в качестве объекта JSON и не включается в результат неэкранированным?
Ответ. Если параметр WITHOUT_ARRAY_WRAPPER указан во внутреннем FOR JSON , создаваемый текст JSON может оказаться недопустимым объектом JSON. Поэтому внешний FOR JSON предполагает, что это обычный текст, и экранирует строку. Если вы уверены, что выходные данные JSON допустимы, заключите их в оболочку с помощью функции JSON_QUERY , чтобы превратить в правильно отформатированную JSON, как показано в следующем примере.
Выходные данные FOR JSON и JSON
Для обработки повторяющихся ключей вместо JSON_VALUE используйте параметр OPENJSON.
Вопрос. В тексте JSON есть повторяющиеся ключи. JSON_VALUE возвращает только первый ключ, найденный в пути. Как возвратить все ключи с одинаковыми именами?
Ответ. Встроенные скалярные функции JSON возвращают только первое вхождение объекта, на который указывает ссылка. Если требуется получить несколько ключей, используйте функцию с табличным значением OPENJSON, как показано в следующем примере.
Вместо JSON_VALUE возвращается длинное текстовое значение с параметром OPENJSON.
Вопрос. В тексте JSON имеется ключ описания, содержащий длинный текст. JSON_VALUE(@json, '$.description') возвращает NULL, а не значение.
Ответ. JSON_VALUE предназначена для возврата небольших скалярных значений. Обычно эта функция возвращает значение NULL вместо ошибки переполнения. Если требуется возвратить более длинные значения, используйте OPENJSON, поддерживающую значения NVARCHAR(MAX), как показано в следующем примере.
Похожие вопросы
OPENJSON необходим уровень совместимости 130
Вопрос. Я пытаюсь запустить OPENJSON в SQL Server 2016, и я получаю следующую ошибку.
Msg 208, Level 16, State 1 'Invalid object name OPENJSON'
Ответ. Функция OPENJSON доступна только при уровне совместимости 130. Если уровень совместимости базы данных ниже 130, функция OPENJSON будет скрыта. Другие функции JSON доступны на всех уровнях совместимости.
Видео Майкрософт
Некоторые ссылки на видео в этом разделе могут не работать в данный момент. Корпорация Майкрософт переносит содержимое, которое ранее транслировалось канале Channel 9, на новую платформу. Мы будем обновлять ссылки по мере переноса видео на новую платформу.
Наглядные инструкции по встроенной поддержке JSON в SQL Server и базе данных SQL Azure см. в следующих видео.
Это краткая статья о наиболее вероятных проблемах с json_encode и их решениях. Иногда при кодировании данных в json, с помощью json_encode в php, мы получаем не тот результат который ожидаем. Я выделил три наиболее частые проблемы с которыми сталкиваются программисты:
- доступ к полям
- кодировка текстовых значений
- цифровые значения
Создание вложенной структуры JSON
Вопрос. Мне нужно создать сложную JSON с несколькими массивами на одном уровне. FOR JSON PATH может создавать вложенные объекты с использованием путей, а FOR JSON AUTO создает дополнительный уровень вложенности для каждой таблицы. Ни один из этих параметров не позволяет мне получить нужный результат. Как создать настраиваемый формат JSON, который напрямую не поддерживается существующими параметрами?
Ответ. Любую структуру данных можно создать, добавив запросы FOR JSON в качестве выражений столбца, возвращающих текст JSON. Кроме того, JSON можно создать вручную с помощью функции JSON_QUERY. Применение этих функции показано в приведенном ниже примере.
Каждый результат запроса FOR JSON или функции JSON_QUERY в выражениях столбца форматируется в виде отдельного вложенного подчиненного объекта JSON и включается в основной результат.
Читайте также: