「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を使用しています。