首页 > 代码库 > JSON转ClientDataSet
JSON转ClientDataSet
这是网上的一段JSON转ClientDataSet和ClientDataSet转JSON的代码.有一个小Bug
else I := I + 2;
导致在中文处理时.解析错误
正确的应该是
else I := I + 1;
汉字Unicode是双字节. I的值本来是1, 加2就是3字节了.导致包含汉字JSON分切的时候老出错.
希望对大家有用
----------------------------------------------------------------------------------
unit JSONDB;
interface
uses
SysUtils, Classes, Variants, DB, DBClient, SuperObject, Dialogs;
type
TJSONDB = class
private
class function getJsonFieldNames(res: ISuperObject): TStringList;
class function getJsonFieldValues(res: ISuperObject): TStringList;
public
class procedure JsonToClientDataSet(jsonArr: TSuperArray; dstCDS: TClientDataSet);
class function ClientDataSetToJSON(srcCDS: TClientDataSet): UTF8String;
end;
implementation
function GetToken(var astring: string; const fmt: array of Char): string;
var
i,j: integer;
Found: Boolean;
begin
found := false;
result := ‘‘;
aString := TrimLeft(aString);
if length(astring) = 0 then exit;
I := 1;
while I <= length(Astring) do
begin
found := false;
if aString[i] <= #128 then
begin
for j := Low(Fmt) to High(Fmt) do
begin
if (astring[i] <> Fmt[j]) then continue;
found := true;
break;
end;
if not found then I := I + 1;
end
else I := I + 2;
if found then break;
end;
if found then
begin
result := copy(astring, 1, i - 1);
delete(astring, 1, i);
end
else
begin
result := astring;
astring := ‘‘;
end;
end;
function GetFieldParams(PropName, Source: string): string;
var
S1, S2: string;
TmpParam: string;
AChar: string;
aValue, aPropName, aSource: string;
begin
Result := ‘‘;
if Source = ‘‘ then Exit;
aSource := Source;
while aSource <> ‘‘ do
begin
aValue := GetToken(aSource, [‘,‘]);
aPropName := GetToken(aValue, [‘:‘]);
if CompareText(PropName, aPropName) <> 0 then continue;
Result := aValue;
break;
end;
end;
//從json取得欄位名稱
class function TJSONDB.getJsonFieldNames(res: ISuperObject): TStringList;
var
i: Integer;
fieldList: TStringList;
fieldNames: string;
begin
try
fieldList := TStringList.Create;
fieldNames := res.AsObject.getNames.AsString;
fieldNames := StringReplace(fieldNames, ‘[‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
fieldNames := StringReplace(fieldNames, ‘]‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
fieldNames := StringReplace(fieldNames, ‘"‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
fieldList.Delimiter := ‘,‘;
fieldList.DelimitedText := fieldNames;
Result := fieldList;
finally
//fieldList.Free;
end;
end;
//從json取得欄位值
class function TJSONDB.getJsonFieldValues(res: ISuperObject): TStringList;
var
i: Integer;
fieldList: TStringList;
fieldValues: string;
begin
try
fieldList := TStringList.Create;
fieldValues := res.AsObject.getValues.AsString;
fieldValues := StringReplace(fieldValues, ‘[‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
fieldValues := StringReplace(fieldValues, ‘]‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
fieldValues := StringReplace(fieldValues, ‘"‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
fieldList.Delimiter := ‘,‘;
fieldList.DelimitedText := fieldValues;
Result := fieldList;
finally
//fieldList.Free;
end;
end;
//json轉CDS
class procedure TJSONDB.JsonToClientDataSet(jsonArr: TSuperArray; dstCDS: TClientDataSet);
var
fieldList: TStringList;
valuesList: TStringList;
jsonSrc: string;
i, j: Integer;
begin
fieldList := getJsonFieldNames(SO[jsonArr[0].AsJson(False, False)]);
if (dstCDS.FieldCount = 0) then
begin
for i := 0 to fieldList.Count - 1 do
begin
dstCDS.FieldDefs.Add(fieldList[i], ftString, 100, False);
end;
dstCDS.CreateDataSet;
dstCDS.Close;
dstCDS.Open;
end;
try
dstCDS.DisableControls;
for i := 0 to jsonArr.Length - 1 do
begin
jsonSrc := SO[jsonArr[i].AsJson(False, False)].AsString;
jsonSrc := StringReplace(jsonSrc, ‘[‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
jsonSrc := StringReplace(jsonSrc, ‘]‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
jsonSrc := StringReplace(jsonSrc, ‘"‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
jsonSrc := StringReplace(jsonSrc, ‘{‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
jsonSrc := StringReplace(jsonSrc, ‘}‘, ‘‘, [rfReplaceAll, rfIgnoreCase]);
dstCDS.Append;
for j := 0 to fieldList.Count - 1 do
begin
dstCDS.FieldByName(fieldList[j]).AsString := GetFieldParams(fieldList[j], jsonSrc);
end;
dstCDS.Post;
end;
finally
dstCDS.EnableControls;
end;
end;
//ClientDataSet轉JSON
class function TJSONDB.ClientDataSetToJSON(srcCDS: TClientDataSet): UTF8String;
var
i, j: Integer;
keyValue: string;
jsonList: TStringList;
jsonResult: string;
begin
if not srcCDS.Active then srcCDS.Open;
try
jsonList := TStringList.Create;
srcCDS.DisableControls;
srcCDS.First;
while not srcCDS.Eof do
begin
keyValue := ‘‘;
for i := 0 to srcCDS.FieldDefs.Count - 1 do
begin
keyValue := keyValue + Format(‘"%s":"%s",‘, [srcCDS.Fields[i].FieldName, srcCDS.Fields[i].AsString]);
end;
jsonList.Add(Format(‘{%s}‘, [Copy(keyValue, 0, Length(keyValue) - 1)]));
srcCDS.Next;
end;
for i := 0 to jsonList.Count - 1 do
begin
jsonResult := jsonResult + jsonList[i] + ‘,‘;
end;
Result := Utf8Encode(Format(‘[%s]‘, [Copy(jsonResult, 0, Length(jsonResult) - 1)]));
finally
srcCDS.EnableControls;
jsonList.Free;
end;
end;
end.