jSon_encode就像接受TDataSet的Delphi函数一样

时间:2013-12-09 21:42:15

标签: delphi

我的任务是在Delphi 2007中创建一个Indy服务器,它与客户端通信并从基于Sql的数据库返回json格式的数据。我们办公室的某个人使用php创建了一个原型。在原型中,他们广泛使用 jSon_encode 函数从表中返回数据。我想知道是否有类似的Delphi函数可以接受 TDataSet 参数并返回格式正确的json数据。

任何人都知道这种功能吗?

2013年12月10日更新 - 我对@ user2748835的修改回答:

function jsonencode(mString: String): String;
begin
  result := StringReplace(mString,'''','\''',[rfReplaceAll,rfIgnoreCase]);
  result := StringReplace(mString,'\','\\',[rfReplaceAll,rfIgnoreCase]);
  result := StringReplace(result,crlf,'\n',[rfReplaceAll,rfIgnoreCase]);
  result := StringReplace(result,'"','\"',[rfReplaceAll,rfIgnoreCase]);
  result := StringReplace(result,'/','\/',[rfReplaceAll,rfIgnoreCase]);
  result := StringReplace(result,'#9','\t',[rfReplaceAll,rfIgnoreCase]);
end;

function jSon_encode(aDataset:TDataset):string;
  function fieldToJSON(thisField:TField):string;
  begin
    try
      result := '"'+thisField.fieldName+'":';
      case thisField.DataType of
        ftInteger,ftSmallint,ftLargeint:
          result := result+inttostr(thisField.AsInteger);
        ftDateTime:
          result := result+'"'+formatdatetime('YYYY-MM-DD HH:NN:SS',thisField.AsDateTime)+'"';
        ftCurrency,
        ftFloat:
          result := result + floattostr(thisField.AsFloat);
        ftString :
          result := result + '"'+jsonencode(thisField.AsString)+'"';
        else
      end; // case
      result := result + ','; 
    except
      on e: Exception do begin
        appendtolog('problem escaping field '+thisfield.fieldname);
      end;
    end;

  end; // of fieldToJSON

  function rowToJSON(ds:TDataset):string;
  var
    fieldIx : integer;
  begin
    result := '';
    for fieldIx := 0 to ds.fieldcount-1 do
      result := result + fieldToJSON(ds.Fields[fieldIx]);
    // trim comma after last col
    result := '{'+copy(result,1,length(result)-1)+'},';
  end; // of rowToJSON
begin
  result := '';
  with aDataset do
  begin
    if not bof then first;
    while not eof do
    begin
      result := result + rowToJSON(aDataset);
      next;
    end;
  end;
  //strip last comma and add
  if length(result)>0 then
    result := copy(result,1,length(result)-1);
  result := '['+result+']';
end; // of DSToJSON

3 个答案:

答案 0 :(得分:2)

在TDataset中,您可以遍历Fields集合并构造json输出,然后在循环中检查fieldtype并相应地对值进行编码。 类似的东西:

uses db;
function DSToJSON(aDataset:TDataset):string;
 function fieldToJSON(thisField:TField):string;
 begin
   result := '"'+thisField.fieldName+'":';
   case thisField.DataType of
   ftInteger,
   ftSmallint,
   ftCurrency,
   ftFloat,
   ftLargeInt:
      result := result+thisField.value+^n^j;
   ftString :
      result := noSingleQuotes(thisField.value)+^n^j;
   else
   end; // case
 end; // of fieldToJSON
  function rowToJSON(ds:TDataset):string;
  var
    fieldIx : integer;
  begin
    for fieldIx := 0 to ds.fieldcount-1 do
      result := result + fieldToJSON(ds.Fields[fieldIx]);
    // trim comma after last col
    result := '{'+copy(result,1,length(result)-1)+'},';
  end; // of rowToJSON
begin
  result := '';
  with aDataset do
  begin
    if not bof then first;
    while not eof do
    begin
      result := result + rowToJSON(aDataset);
      next;
    end;
  end;
  //strip last comma and add
  if length(result)>0 then
    result := copy(result,1,length(result)-1);
  result := '['+result+']';
end; // of DSToJSON

答案 1 :(得分:2)

我们刚刚在我们的开源存储库中添加了一个更完整,更快速的功能。

它是我们 mORMot 框架的一部分,但可以作为独立单元使用,与其他功能无关。

SynVirtualDataSet.pas

function DataSetToJSON(Data: TDataSet): RawUTF8 

请参阅this commitassociated forum thread

答案 2 :(得分:0)

您可以将每一行更改为对象,并使用序列化http://docwiki.embarcadero.com/RADStudio/XE5/en/Serializing_User_Objects