Delphi XE6中如何将TJsonValue转换为合法JSON字符串?
在Delphi XE6中将TJsonValue转换为合法JSON字符串
在Delphi XE6环境下,通过TJSONObject.ParseJSONValue解析JSON字符串得到TJsonValue派生对象后,要转成符合规范的JSON字符串,内置方法存在诸多缺陷:
ToString():输出的是人类可读格式,未正确转义CR、LF这类控制字符,生成的JSON不合法ToJson():该方法在XE6版本中尚未提供,无法直接使用ToBytes():会无差别转义所有ASCII码大于127的字符,不符合需求- 手动修复
ToString()结果:无法覆盖所有ASCII码小于32的控制字符,遗漏风险高
下面给出两种可行的解决办法:
办法一:自定义JSON序列化函数
通过友元类访问TJsonString的受保护成员FStrBuffer获取原始字符串,再手动实现完整的JSON转义逻辑,同时覆盖所有TJsonValue的派生类型(对象、数组、字符串、数字、布尔、空值)。
步骤1:定义友元类访问受保护成员
type TJsonStringHelper = class(TJsonString) public function GetStrBuffer: string; end; function TJsonStringHelper.GetStrBuffer: string; begin Result := Self.FStrBuffer; end;
步骤2:实现核心序列化函数
function JsonValueToJSON(Value: TJsonValue): string; var I: Integer; Pair: TJsonPair; Arr: TJsonArray; Obj: TJsonObject; StrVal: TJsonString; begin if Value = nil then begin Result := 'null'; Exit; end; case Value.JsonValueType of jvtNull: Result := 'null'; jvtBoolean: Result := BoolToStr(TJsonBool(Value).Value, True); jvtNumber: Result := TJsonNumber(Value).ToString; jvtString: begin StrVal := TJsonString(Value); Result := '"' + EscapeJSONString(TJsonStringHelper(StrVal).GetStrBuffer) + '"'; end; jvtArray: begin Arr := TJsonArray(Value); Result := '['; for I := 0 to Arr.Count - 1 do begin if I > 0 then Result := Result + ','; Result := Result + JsonValueToJSON(Arr.Items[I]); end; Result := Result + ']'; end; jvtObject: begin Obj := TJsonObject(Value); Result := '{'; for I := 0 to Obj.Count - 1 do begin Pair := Obj.Pairs[I]; if I > 0 then Result := Result + ','; Result := Result + '"' + EscapeJSONString(Pair.JsonString.Value) + '":' + JsonValueToJSON(Pair.JsonValue); end; Result := Result + '}'; end; end; end;
步骤3:实现JSON转义函数
function EscapeJSONString(const S: string): string; var I: Integer; C: Char; begin Result := ''; for I := 1 to Length(S) do begin C := S[I]; case C of #8: Result := Result + '\b'; #9: Result := Result + '\t'; #10: Result := Result + '\n'; #12: Result := Result + '\f'; #13: Result := Result + '\r'; '"': Result := Result + '\"'; '\': Result := Result + '\\'; '/': Result := Result + '\/'; #0..#31: begin // 转义为Unicode标准转义序列 Result := Result + '\u' + IntToHex(Word(C), 4); end; else Result := Result + C; end; end; end;
该方案需要自行处理所有JSON类型的转换,但能严格遵循JSON规范,避免不必要的转义。
办法二:使用第三方JSON库
如果不想手动实现序列化逻辑,可以选择兼容Delphi XE6的成熟第三方库,比如SuperObject或mORMot的JSON模块,这些库自带完善的序列化功能,无需手动处理转义细节。
以SuperObject为例:
uses SuperObject; var Obj: ISuperObject; JsonStr: string; begin // 解析JSON字符串 Obj := SO(JsonStr); // 序列化为合法JSON字符串 JsonStr := Obj.AsJSON; end;
内容的提问来源于stack exchange,提问作者Ian Boyd
相关产品推荐
相关产品推荐

