clientdataset<---->json
现在,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;
clientdataset<---->json的更多相关文章
- JSON和数据集互相转换单元
如题......只是一个单元, 为了测试JSON单元性能的... 具体测试结果参考: http://www.cnblogs.com/hs-kill/p/3668052.html 代码中用到的Seven ...
- DataSnap 多层返回数据集分析FireDAC JSON
采用服务器返回数据,一种是返回字符串数据例如JSON,跨平台跨语言,任何语言调用都支持兼容,类似WEBService. 第二种是紧密结合c++builder语言,传输DataSet,可以是Client ...
- delphi中json转dataset
unit uJSONDB; interface uses SysUtils, Classes, Variants, DB, DBClient, SuperObject, Dialogs; type T ...
- 使用TSQL查询和更新 JSON 数据
JSON是一个非常流行的,用于数据交换的文本数据(textual data)格式,主要用于Web和移动应用程序中.JSON 使用“键/值对”(Key:Value pair)存储数据,能够表示嵌套键值对 ...
- 【疯狂造轮子-iOS】JSON转Model系列之二
[疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...
- 【疯狂造轮子-iOS】JSON转Model系列之一
[疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...
- Taurus.MVC 2.2 开源发布:WebAPI 功能增强(请求跨域及Json转换)
背景: 1:有用户反馈了关于跨域请求的问题. 2:有用户反馈了参数获取的问题. 3:JsonHelper的增强. 在综合上面的条件下,有了2.2版本的更新,也因此写了此文. 开源地址: https:/ ...
- .NET Core系列 : 2 、project.json 这葫芦里卖的什么药
.NET Core系列 : 1..NET Core 环境搭建和命令行CLI入门 介绍了.NET Core环境,本文介绍.NET Core中最重要的一个配置文件project.json的相关内容.我们可 ...
- 一个粗心的Bug,JSON格式不规范导致AJAX错误
一.事件回放 今天工作时碰到了一个奇怪的问题,这个问题很早很早以前也碰到过,不过没想到过这么久了竟然又栽在这里. 当时正在联调一个项目,由于后端没有提供数据接口,于是我直接本地建立了一个 json ...
随机推荐
- CSS 实现图片灰度效果 兼容各种浏览器
CSS 实现图片灰度效果 兼容各种浏览器如360浏览器 CSS实现图片灰度效果就是通过CSS样式让彩色图片呈现为灰色,相当于把一张图像的颜色模式调整为灰度,CSS可以通过以下几种方法来实现灰度效果. ...
- USACO Longest Prefix 【水】
用Dp的思想解决了这道题目,也就是所谓的暴力= = 题意:给出一个集合,一个字符串,找出这个字符串的最长前缀,使得前缀可以划分为这个集合中的元素(集合中的元素可以不全部使用). 还不会Trie 树QA ...
- XCode 快速注释插件
下载VVDocumenter-Xcode这个插件 打开编译后,重启Xcode 输入///,如效果图,Window->VVDocumenter自己定制风格
- Windows系统命令行net user命令用法
在Windows渗透测试过程中,最常用的要数net user 命令了,但是非常多的时候我们都是对Linux命令非常熟悉,对Windows命令非常熟悉或者了解用法的少只有少,为了以后工作方便,这里记录一 ...
- docker学习笔记11:Dockerfile 指令 CMD介绍
我们知道,通过docker run 创建并启动一个容器时,命令的最后可以指定容器启动后在容器内立即要执行的指令,如: docker run -i -t ubunu /bin/bash //表示容器 ...
- python _thread模块使用
python关于线程管理的有2个类,_thread(在2.x的版本中叫thread)和threading. # encoding: UTF-8 import thread import time ...
- CentOS下Samba文件服务器的安装与配置
CentOS下Samba文件服务器的安装与配置 http://blog.csdn.net/limingzhong198/article/details/22064801 一.安装配置 1. 安装sam ...
- C语言数据结构-创建链表的四种方法
结点类型: typedef int datatype; typedef struct NODE{ datatype data; struct NODE *next; }Node,*LinkList; ...
- 13-UIKit(tableviewcell贴图、手势GestureRecognizer、transform变形)
目录: 一.tableviewcell贴图 二.手势GestureRecognizer 5.1 Tap(按一下) 5.2 Swipe(轻扫一下) 5.3 pinch(捏/扩) 5.4 longPres ...
- servlet的url-pattern匹配规则详细描述
一.概述 在利用servlet或Filter进行url请求的匹配时,很关键的一点就是匹配规则,但servlet容器中的匹配规则既不是简单的通配,也不是正则表达式,而是由自己的规则,比较容易混淆.本文来 ...