现在,DATASNAP倾向于使用JSON作为统一的数据序列格式,以期达到跨平台的效果。于是使用JSON便成为热点。

unit uJSONDB;
 
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.

使用範例

//取得資料
procedure TForm1.btnRefreshClick(Sender: TObject);
var
  getString:string;
  json: ISuperObject;
  ja: TSuperArray;
begin
  try
    getString := idhtp1.Get('http://localhost/xuan/wsLine.php');
    json :=SO(getString);
    ja := json.AsArray;
 
    TJSONDB.JsonToClientDataSet(ja, cdsMain);
  finally
 
  end;
end;
//寫入資料
procedure TForm1.btnSubmitClick(Sender: TObject);
var
  jsonString:string;
  jsonStream:TStringStream;
begin
  if cdsNew.State in [dsEdit] then cdsNew.Post;
  try
    jsonString:= TJSONDB.ClientDataSetToJSON(cdsNew);
 
    jsonStream := TStringStream.Create(jsonString);
 
    idhtp1.HandleRedirects := True;
    idhtp1.ReadTimeout := 5000;
    idhtp1.Request.ContentType := 'application/json';
    idhtp1.Post('http://localhost/xuan/wsLine.php?action=insert',jsonStream);
 
  finally
    jsonStream.Free;
  end;
end;
 http://www.cnblogs.com/hnxxcxg/archive/2013/02/20/2919813.html

clientdataset<---->json的更多相关文章

  1. JSON和数据集互相转换单元

    如题......只是一个单元, 为了测试JSON单元性能的... 具体测试结果参考: http://www.cnblogs.com/hs-kill/p/3668052.html 代码中用到的Seven ...

  2. DataSnap 多层返回数据集分析FireDAC JSON

    采用服务器返回数据,一种是返回字符串数据例如JSON,跨平台跨语言,任何语言调用都支持兼容,类似WEBService. 第二种是紧密结合c++builder语言,传输DataSet,可以是Client ...

  3. delphi中json转dataset

    unit uJSONDB; interface uses SysUtils, Classes, Variants, DB, DBClient, SuperObject, Dialogs; type T ...

  4. 使用TSQL查询和更新 JSON 数据

    JSON是一个非常流行的,用于数据交换的文本数据(textual data)格式,主要用于Web和移动应用程序中.JSON 使用“键/值对”(Key:Value pair)存储数据,能够表示嵌套键值对 ...

  5. 【疯狂造轮子-iOS】JSON转Model系列之二

    [疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...

  6. 【疯狂造轮子-iOS】JSON转Model系列之一

    [疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...

  7. Taurus.MVC 2.2 开源发布:WebAPI 功能增强(请求跨域及Json转换)

    背景: 1:有用户反馈了关于跨域请求的问题. 2:有用户反馈了参数获取的问题. 3:JsonHelper的增强. 在综合上面的条件下,有了2.2版本的更新,也因此写了此文. 开源地址: https:/ ...

  8. .NET Core系列 : 2 、project.json 这葫芦里卖的什么药

    .NET Core系列 : 1..NET Core 环境搭建和命令行CLI入门 介绍了.NET Core环境,本文介绍.NET Core中最重要的一个配置文件project.json的相关内容.我们可 ...

  9. 一个粗心的Bug,JSON格式不规范导致AJAX错误

    一.事件回放  今天工作时碰到了一个奇怪的问题,这个问题很早很早以前也碰到过,不过没想到过这么久了竟然又栽在这里. 当时正在联调一个项目,由于后端没有提供数据接口,于是我直接本地建立了一个 json ...

随机推荐

  1. 独立搭建zookeeper

    1.如果你装了带有zookeeper的Hbase版本,先把hbase-env.sh   export HBASE_MANAGES_ZK=false 设置为false 见下图 2.下载安装zookeep ...

  2. POJ 2208 Pyramids 欧拉四面体

    给出边长,直接就可以求出体积咯 关于欧拉四面体公式的推导及证明过程 2010-08-16 14:18 1,建议x,y,z直角坐标系.设A.B.C少拿点的坐标分别为(a1,b1,c1),(a2,b2,c ...

  3. Chapter 1.简单工厂模式

    该篇文章通过一个写计算器控制台程序,来导入文章主题. 首先,要注意代码规范,变量命名有意义,不能随意用A,B,C;    功能要封装好,不要写在一个主函数里,另外要考虑后期需求的更改,如果出现多个函数 ...

  4. WPF:DataTemplateSelector设置控件不同的样式

    原文 WPF:DataTemplateSelector设置控件不同的样式 最近想实现这么个东西,一个ListBox, 里面的ListBoxItem可能是文本框.下拉框.日期选择控件等等. 很自然的想到 ...

  5. python 正则表达式汇总

    一. 正则表达式基础 1.1.概念介绍 正则表达式是用于处理字符串的强大工具,它并不是Python的一部分. 其他编程语言中也有正则表达式的概念,区别只在于不同的编程语言实现支持的语法数量不同. 它拥 ...

  6. WebFetch 是无依赖极简网页爬取组件

    WebFetch 是无依赖极简网页爬取组件,能在移动设备上运行的微型爬虫. WebFetch 要达到的目标: 没有第三方依赖jar包 减少内存使用 提高CPU利用率 加快网络爬取速度 简洁明了的api ...

  7. cocos2d-x游戏开发系列教程-超级玛丽01-前言

    前言 上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实现,并以一些篇幅来详细讲述遇到的具体问题和具体的 ...

  8. jQuery动态添加删除select项

    // 添加 function col_add() { var selObj = $("#mySelect"); var value="value"; var t ...

  9. Sort List 分类: leetcode 算法 2015-07-10 15:35 1人阅读 评论(0) 收藏

    对链表进行排序,要求时间复杂度为O(n log n) ,不使用额外的空间. 我一开始的想法是借助quicksort的思想,代码如下: # time O(nlog(n)) # Definition fo ...

  10. Eclipse 和 MyEclipse控制台console不停的自动跳动,跳出来解决方案

    有时候Eclipse启动,控制台console不会自动跳出来,需要手工点击该选项卡才行,按下面的设置,可以让它自动跳出来(或不跳出来):由二种方法: 一.windows  ->   prefer ...