JSON文字列のエスケープについて

cppBuilder – c++ builder / JSON > "\"付きの文字列の扱いに失敗する > "\"ではなく"\\"にする – Qiita」を読んで、JSONについて調べてみた。

受け取った文字列をTJSONObjectに変換して表示する関数を作成する。

uses
  System.JSON;

procedure Print(const JSONStr: string);
var
  JSONValue: TJSONValue;
  JSONObj: TJSONObject;
  JSONPair: TJSONPair;
begin
  JSONValue := TJSONObject.ParseJSONValue(JSONStr);
  if JSONValue = nil then
    ShowMessage('解析に失敗しました。')
  else
  begin
    JSONObj := JSONValue as TJSONObject;
    try
      for JSONPair in JSONObj do
        ShowMessage(JSONPair.JsonString.Value + '=' + JSONPair.JsonValue.Value);
    finally
      JSONObj.Free;
    end;
  end;
end;

文字列に「\」がなければ正常に動作する。

procedure TForm1.Button1Click(Sender: TObject);
const
  JSONStr = '{"Delphi":"Object Pascal", "C++Builder":"C++"}';
begin
  Print(JSONStr);
end;

文字列に「\」があると解析に失敗する。

procedure TForm1.Button2Click(Sender: TObject);
const
  JSONStr = '{"name":"C:\Windows", "age":"33"}';
begin
  Print(JSONStr);
end;

JSONの仕様はRFC 7159に定義されている。
RFC 4627は古い仕様である)

RFC 7159によると、「”」「\」「/」「b」「f」「n」「r」「t」「uXXXX」は「\」でエスケープすることになっている。

"    quotation mark  U+0022
\    reverse solidus U+005C
/    solidus         U+002F
b    backspace       U+0008
f    form feed       U+000C
n    line feed       U+000A
r    carriage return U+000D
t    tab             U+0009
uXXXX                U+XXXX

したがって、先ほど解析に失敗するコードは「\」をエスケープする必要があった。

const
  //JSONStr = '{"name":"C:\Windows", "age":"33"}';
  JSONStr = '{"name":"C:\\Windows", "age":"33"}';

TJSONObject.ParseJSONValue関数は解析に失敗するとnilを返す。
戻り値がnilかどうかをチェックすることを忘れないようにしたい。

サンプルコードはDelphi 10 Seattleを使用しています。

DelphiのJSON関連の記事

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください