08 ноября 2019

Формирование строкового значения для JSON

    При формировании строки для строкового значения JSON возникает необходимость контролировать некоторые символы. Например, если в содержимом строки есть двойная кавычка, то для получения строки JSON недостаточно взять исходную строку в двойные кавычки. Это двойную кавычку необходимо "экранировать" - поставить перед ней символ обратной косой черты ("\"). Кроме двойной кавычки обязательно необходимо экранировать саму обратную косую черту, а также все управляющие символы от U+0000 до U+001F (т.е. символы от 0 до 31).
    Рассмотрим подробнее, как экранируются символы. Любой символ от U+0000 до U+FFFF (не только управляющий) в строке JSON может быть представлен в виде последовательности из шести символов: обратный косая черта, строчная буква u, код символа в виде четырех шестнадцатеричные цифр. Буквы в шестнадцатеричные цифрах не зависят от регистра и могут быть как прописными, так и строчными. Например, буква "ё" представляется как "\u0451", а буква "к" как "\u043A".
    Среди управляющих символов выделены "специальные символы", которые в строке JSON представлены в виде комбинации обратной косой черты и символа:

Специальный символ Представление в строке JSON
Кавычки (quotation mark)  "  U+0022 \"
Обратная косая черта (reverse solidus) \ U+005C \\
Косая черта (solidus) / U+002F \/
Backspace U+000C \b
Подача страницы (form feed) U+000C \f
Перевод строки (line feed) U+000A \n
Возврат каретки (carriage return) U+000D \r
Табуляция (tab) U+0009 \t

    Теперь от теории перейдем к практике. Можно самому написать парсер строки, который экранирует управляющие символы по описанным выше правилам, а можно воспользоваться готовым классом TJSONString из модуля System.JSON:
function ToJsonString(const st: String): String;
var
  js: TJSONString;
begin
  js := TJSONString.Create(st);
  try
    Result := js.ToString;
  finally
    js.Free;
  end;
end;
Передав этой функции строку:
Путь к нашему файлу: "c:\temp\от 1 до 2"
получим следующий результат:
"Путь к нашему файлу:\t\"c:\\temp\\от 1 до 2\""
Кроме читаемого человеком формата, из TJSONString можно получить JSON-строку в формате UTF8 в которой экранированы не только управляющие символы, но все символы начиная с +U0080, т.е. с 128-го символа (например, кириллические символы):
function ToJsonString(const st: String): String;
var
  js: TJSONString;
begin
  js := TJSONString.Create(st);
  try
    Result := js.ToJSON;
  finally
    js.Free;
  end;
end;
Передадим новой версии функции аналогичную строку:
Путь к нашему файлу: "c:\temp\от 1 до 2"
И получим вот такой не пригодный для чтения человеком результат:
"\u041F\u0443\u0442\u044C \u043A \u043D\u0430\u0448\u0435
\u043C\u0443 \u0444\u0430\u0439\u043B\u0443:\t\"c:\\temp\\
\u043E\u0442 1 \u0434\u043E 2\""
Но его замечательно понимают парсеры JSON.

Литература:
Стандарт The application/json Media Type for JavaScript Object Notation (JSON)

1 комментарий: