json,System.JSON,REST.JSON
JSON有两种数据结构,对象和数组。
对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,...}
数组在js中是中括号“[]”括起来的内容,数据结构为 ["java","javascript","vb",...]
{
"NAME":"DVAD",
"SEX":"MAN",
"AGE":12
}
https://community.embarcadero.com/blogs/entry/how-to-make-restful-webbroker-using-c-builder
jo用完记得释放 jo.free;
root['child.name']
http://docwiki.embarcadero.com/Libraries/Berlin/en/System.JSON.TJSONObject
一、 System.Json.Readers JSONWriter
System.Json.Readers,System.Json.Writers, System.Json.Types
TJsonReader\TJsonTextWriter,与.net的Newtonsoft JsonTextReader 、JsonTextWriter相同,是RAD10 Settle版新增的功能。
http://docwiki.embarcadero.com/CodeExamples/Berlin/en/RTL.JSONWriter
{ "id": "001", "name": "aaa", "age": 99 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
procedure TFrmLogin.Button2Click( Sender : TObject ); var writer : TJsonTextWriter; sw : TStringWriter; begin sw := TStringWriter.Create; writer := TJsonTextWriter.Create( sw ); writer.Formatting := TJsonFormatting.Indented; writer.WriteStartObject; writer.WritePropertyName( 'id' ); writer.WriteValue( '001' ); writer.WritePropertyName( 'name' ); writer.WriteValue( 'aaa' ); writer.WritePropertyName( 'age' ); writer.WriteValue( 99 ); writer.WriteEndObject; self.Memo1.Text := sw.ToString; sw.Free; end;
相比较JSONBuilder更清晰,吸收了java的优点。java参考 http://docs.oracle.com/javaee/7/api/javax/json/JsonObjectBuilder.html
http://docwiki.embarcadero.com/CodeExamples/Seattle/en/RTL.JSONBuilder
http://docwiki.embarcadero.com/CodeExamples/Berlin/en/RTL.JSONBuilder
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
uses System.SysUtils, System.Classes, System.JSON.Types, System.JSON.Writers; System.JSON.Builders; var Builder: TJSONObjectBuilder; Writer: TJsonTextWriter; StringWriter: TStringWriter; StringBuilder: TStringBuilder; begin StringBuilder := TStringBuilder.Create; StringWriter := TStringWriter.Create(StringBuilder); Writer := TJsonTextWriter.Create(StringWriter); Writer.Formatting := TJsonFormatting.Indented; Builder := TJSONObjectBuilder.Create(Writer); Builder .BeginObject .BeginArray('Transaction') .BeginObject.Add('id', 662713) .Add('firstName', 'John') .Add('lastName', 'Doe') .Add('price', 2.1) .AddNull('parent_id') .Add('validated', true) .EndObject .BeginObject .Add('id', 662714) .Add('firstName', 'Anna') .Add('lastName', 'Smith') .Add('price', 4.5) .AddNull('parent_id') .Add('validated', false) .EndObject .BeginObject .Add('id', 662715) .Add('firstName', 'Peter') .Add('lastName', 'Jones') .Add('price', 3.6) .AddNull('parent_id') .Add('validated', true) .EndObject .EndArray .EndObject; WriteLn(StringBuilder.ToString);
生成的json字符串
{"Transaction":[ {"id":662713, "firstName":"John", "lastName":"Doe", "price": 2.1, "parent_id": null, validated:true}, {"id":662714, "firstName":"Anna", "lastName":"Smith", "price": 4.5, "parent_id": null, validated: false}, {"id":662715, "firstName":"Peter", "lastName":"Jones", "price": 3.6, "parent_id": null, validated: true} ]}
二、System.JSON.pas
System.JSON.pas
#include <System.JSON.hpp>
TJSONArray* jar = (TJSONArray*)TJSONObject::ParseJSONValue(Memo3->Text); jar->Count; for (int i = 0; i < jar->Size(); i++) { TJSONValue *jv = jar->Get(i); jv = ((TJSONArray*)jv)->Get(1); TJSONPair *jp = (TJSONPair*)jv; jp->JsonString->Value();//值字段名 jp->JsonValue->Value();//取值 if (jp->JsonValue->Value() == "1") // 判断值 { jar->Remove(i); break; } } // jar->Remove(1); Memo3->Text = jar->ToString(); delete jar;
TJSONObject *JSON = (TJSONObject*)TJSONObject::ParseJSONValue(Memo2->Text);
TJSONArray* jArray = (TJSONArray*)JSON->Get("adverts")->JsonValue;
jar->Items[0]->Value();
TJSONObject* jCompanyInfo = (TJSONObject*)((TJSONObject*)jArray->Get(0))->Get("companyInfo")->JsonValue;
String companyName = jCompanyInfo->Get("companyName")->JsonValue->Value();
-
自己测试的例子
[
{
"cmd":32,
"error":"",
"data":[
{"cp":"xx1", "js":"5124", "jsqwz":"xxx1","b":"2012"},
{"cp":"xx2", "js":"5124", "jsqwz":"xxx2","b":"2013"},
{"cp":"xx3", "js":"5124", "jsqwz":"xxx3","b":"2014"}
]
}]
TJSONObject *JSON = (TJSONObject*)TJSONObject::ParseJSONValue(Memo4->Text); JSON = (TJSONObject*)JSON->Get(0); JSON->Count; ((TJSONPair*)JSON->Get("cmd"))->JsonString->Value(); ((TJSONPair*)JSON->Get("cmd"))->JsonValue->Value(); ((TJSONPair*)JSON->Get("error"))->JsonString->Value(); ((TJSONPair*)JSON->Get("error"))->JsonValue->Value();
TJSONArray *jar = (TJSONArray*) jo->Get("data")->JsonValue; //TJSONArray *jar = (TJSONArray*)((TJSONPair*)JSON->Get("data")->JsonValue); for (int i = 0; i < jar->Count; i++) { for (int j = 0; j < 4; j++) { Caption = ((TJSONPair*)((TJSONArray*)jar->Get(i))->Get(j))->JsonString->Value(); Caption = ((TJSONPair*)((TJSONArray*)jar->Get(i))->Get(j))->JsonValue->Value(); } }
delphi写法
jo := jv as TJSONObject; jar := jo.GetValue('Column') as TJSONArray; for I := 0 to jar.Count - 1 do begin jar.Get(I) as TJSONValue).Value; end;
jar := jo.GetValue('data') as TJSONArray; for I := 0 to jar.Count - 1 do begin
jo := jar.Get(I) as TJSONObject;
Caption := jo.Values['cp'].Value; // value字段名访问 (1)
Caption := jo.GetValue('cp').Value;// getvalue 字段名访问(2)
Caption =jo.getValue('cp',''); // jv := jar.Get(I); // Caption := jv.GetValue('cp', ''); // for j := 0 to jo.Count - 1 do begin Caption := jo.Pairs[j].JsonValue.Value; // Pairs 索引遍历访问 (3) Caption := jo.Values[jo.Pairs[j].JsonString.Value].Value; // Values索引遍历访问(4) end; // Break; end;
生成json
TJSONObject *OBJ = new TJSONObject();
OBJ->AddPair("Result", "1");
OBJ->AddPair("Text", "密码不正确");
OBJ->AddPair("DATA", jsonArray);//这样也可以
Memo5->Text = OBJ->ToString(); //OBJ->ToString(); ToJSON
#include "Data.DBXJSONCommon.hpp"
TDBXReader *reader;
TJSONObject *jsobj=TDBXJSONTools::TableToJSON(reader,10,true);
String jsstr=jsob.ToString
arr: TJSONArray;
arr := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(''), 0) as TJSONArray;
FClient: TRESTClient;
FRequest: TRESTRequest;
FDataSets: TFDJSONDataSets;
LJSONObj := FRequest.Response.JSONValue.GetValue<TJSONArray>('result').Items[0] as TJSONObject;
jsonValue->GetValue<String>("rID")
LUnmarshaller := TJSONUnMarshal.Create;
FDataSets := LUnmarshaller.Unmarshal(LJSONObj) as TFDJSONDataSets;
三、delphi 最常用最简单的json解析
{"Work":"err","Plan":"err"}
1)用TJSONValue解析
TJSONValue ToJSON和ToString的区别。
TJSONString System.JSON.pas
jv.ToJSON 、汉字是Unicode符号\xxxx,有转移字符,例如/ 转出json串 \/,传输比较安全,语法正确。
jv.ToString 汉字是真实的汉字,无需转换,但是多了\,需要删除处理,没有转移字符会报错。
jv.Value : 汉字是真实的unicode,没有多余的\,直接使用。
delphi json 汉字 Unicode编码说明.
procedure TForm22.Button1Click(Sender: TObject); var jv: TJSONValue; begin jv := TJSONObject.ParseJSONValue(self.Memo1.Text); self.Caption := jv.GetValue('Work', '');
jv.GetValue('Plan', '');
end;
str:= jo.GetValue('result.token',''); str:= jo.GetValue<string>('result.token');
jarr := jo.GetValue<TJSONArray>('result.list') ;
带路径path获取json值。方便的json,推荐,这些就省得一层一层转换了。
2)用TJSONObject也可以。
procedure TForm1.Button3Click(Sender: TObject); var jo: TJSONObject; begin jo := TJSONObject.ParseJSONValue(self.Memo1.Text) as TJSONObject; self.Caption := jo.GetValue('Success', ''); jo.GetValue('Plan', ''); end;
//delphi 语法 json A节点下B的值
jo.Values['responseInfo'].GetValue('isSuccess', '');
jo.Get('Name').JsonValue.Value
TJSONString(ja.Get(0)).Value;
C++语法
jo->Values["aname"];
jo->Values["aname"]->Value();
jv->GetValue<String>("aname");
TJSONObject *jo = (TJSONObject*)TJSONObject::ParseJSONValue(Memo1->Text);
this->Caption = jo->Values["code"]->Value();
this->Caption = jo->Values["code"]->ToJSON();
this->Caption = jo->Values["code"]->ToString();
http://docwiki.embarcadero.com/CodeExamples/Seattle/en/RTL.JSONReader
"{"responseInfo":{"isSuccess":"-1","errMsg":"设备连接异常"}}" TStringReader *sr = new TStringReader(out); TJsonTextReader * reader = new TJsonTextReader(sr); reader->Read(); reader->Read(); reader->Read(); reader->Read(); reader->TokenType; reader->Path; String www = reader->Value.ToString(); String aaa = reader->ReadAsString();
TJSONObject *JSON = (TJSONObject*)TJSONObject::ParseJSONValue(String(out)); TJSONArray *jar = (TJSONArray*) JSON->Get("responseInfo")->JsonValue; jar->Count;//2 TJSONPair *jp= (TJSONPair*) jar->Get(0); aaaaaa= jp->JsonString->Value();//isSuccess aaaaaa= jp->JsonValue->Value();//-1
http://stackoverflow.com/questions/14864170/how-to-parse-a-json-array-in-rad-studio
RAD10,很多资料
http://www.cnblogs.com/HuiLove/p/4006248.html
http://community.embarcadero.com/blogs/entry/learn-how-to-use-the-new-json-features-in-rad-studio-10-seattle-webinar-march-2nd-wednesday
Delphi JSON Viewer (executable): http://cc.embarcadero.com/Item/30495 树形查看器
LJSONObject: TJSONObject; LJSONObject := TJSONObject.ParseJSONValue(MemoJSONUser.Text) as TJSONObject;
JSONObject.Values['name'].ToString
LJSONValue: TJSONValue; LPair: TJSONPair; LJSONValue := TJSONObject.ParseJSONValue(BytesOf(E.ResponseText), 0); if LJSONValue is TJSONObject then begin LPair := TJSONObject(LJSONValue).Get(0); if LPair.JsonString.Value = 'SessionExpired' then // Clear session id because it is no good AConnection.SessionID := ''; // Extract error message LMessage := LPair.JSONValue.Value; end; LAcctType := TJSONArray(LPair.JSONValue).Get(0).Value; LAcctName := TJSONArray(LPair.JSONValue).Get(1).Value; LAcctKey := TJSONArray(LPair.JSONValue).Get(2).Value;
jo: TJSONObject;
str:=jo.Get('ResultValue').JsonValue.GetValue('Total','');
iaint:=jo.Get('ResultValue').JsonValue.GetValue('Total','').ToInteger;
svalue = jo->GetValue("data")->GetValue<String>("token", "");//c++
嵌套JSON下面这2种都可以。
{
"time": "2016-06-24 08:07:40",
"data": {
"token": "4a414be399650d68e010bdb366790f78",
"validTime": "288000"
}
}
self.Caption := jo.Get('data').JsonValue.GetValue('token', '');
self.Caption := jo.GetValue('data').GetValue('token','');
TJsonToken = (
None,
StartObject,
StartArray,
StartConstructor,
PropertyName,
Comment,
Raw,
Integer,
Float,
&String,
Boolean,
Null,
Undefined,
EndObject,
EndArray,
EndConstructor,
Date,
Bytes,
// Extended JSON
Oid,
RegEx,
DBRef,
CodeWScope,
MinKey,
MaxKey
);
三、REST.JSON.pas
TJson.ObjectToJsonString
"P_TYPE" : "2",
"PatientID" : "0000023561",
"LISTNO" : "2353",
"PIC_DATA" : [{
"PIC_ID" : "1",
"data" : "111111111111"
}, {
"PIC_ID" : "2222222222222222",
"data" : ""
}, {
"PIC_ID" : "333333333333333333333",
"data" : ""
}
]
}
TJSONObject *OBJ = new TJSONObject(); OBJ->AddPair("AA", "2"); OBJ->AddPair("BB", "0000023561"); OBJ->AddPair("CC", "2353"); TJSONArray *arr; arr = new TJSONArray(); TJSONObject *jv = new TJSONObject(); jv->AddPair("PIC_ID", "1"); jv->AddPair("data", ("1")); arr->AddElement(jv); jv = new TJSONObject(); jv->AddPair("PIC_ID", "2"); jv->AddPair("data", ("22222")); arr->AddElement(jv); jv = new TJSONObject(); jv->AddPair("PIC_ID", "3"); jv->AddPair("data", ("3333")); arr->AddElement(jv); OBJ->AddPair("PIC_DATA", arr);
var ja: TJSONArray; begin ja := TJSONArray.Create; ja.AddElement(TJSONString.Create('abc')); ja.AddElement(TJSONNumber.Create(123)); ja.AddElement(TJSONBool.Create(true)); Memo1.Text:= ja.ToString;
{"name":"james","age":38,"marry":true}有名称的值。
var jo:TJSONObject; begin jo := TJSONObject.Create; jo.AddPair('name',TJSONString.Create('james')); jo.AddPair('age',TJSONNumber.Create(38)); jo.AddPair('marry',TJSONBool.Create(true)); self.Memo1.Text:=jo.ToString;
["abc",123,true,{"book":"james","bank":38,"phone":true}]
var ja: TJSONArray; jo: TJSONObject; begin ja := TJSONArray.Create; ja.AddElement(TJSONString.Create('abc')); ja.AddElement(TJSONNumber.Create(123)); ja.AddElement(TJSONBool.Create(true)); jo := TJSONObject.Create; jo.AddPair('book', TJSONString.Create('james')); jo.AddPair('bank', TJSONNumber.Create(38)); jo.AddPair('phone', TJSONBool.Create(true)); ja.AddElement(jo);
//ja.Add(jo);
jo.AddPair('ret',TJSONNull.Create);
ja.AddElement(TJSONString.Create('james'));
ja.AddElement(TJSONNumber.Create(38));
class function TNoteJSON.JSONToNotes(const AJSON: TJSONArray): TArray<TNote>; var LValue: TJSONValue; LList: TList<TNote>; begin LList := TList<TNote>.Create; try for LValue in AJSON do LList.Add(TNoteJSON.JSONToNote(LValue)); Result := LList.ToArray; finally LList.Free; end; end;
json迭代器TJSONIterator
http://docwiki.embarcadero.com/CodeExamples/Berlin/en/RTL.JSONIterator
LIterator.Next;
LIterator.Recurse; // enter array object
LIterator.Key +': '+ LIterator.AsString
LIterator.Return; // back to parent structure
c++builder的迭代器
https://community.embarcadero.com/blogs/entry/how-to-get-the-array-using-the-tjsoniterator-delphi-japan
It is a new function of 10.2.2, and it can be outputted by Ext JS store definition.
https://community.embarcadero.com/blogs/entry/it-is-a-new-function-of-10-2-2-and-it-can-be-outputted-by-ext-js-store-definition
function TServerMethods1.GetDepartmentNames: TFDJSONDataSets; begin // Clear active so that query will reexecute FDQueryDepartmentNames.Active := False; Result := TFDJSONDataSets.Create; TFDJSONDataSetsWriter.ListAdd(Result, FDQueryDepartmentNames); end;
function TServerMethods1.GetDepartmentNamesJSON: TJSONObject; var LDataSets: TFDJSONDataSets; begin LDataSets := GetDepartmentNames; try Result := TJSONObject.Create; TFDJSONInterceptor.DataSetsToJSONObject(LDataSets, Result); finally LDataSets.Free; end; end;
function TServerMethods1.GetDepartmentNames: TFDJSONDataSets; begin // Clear active so that query will reexecute FDQueryDepartmentNames.Active := False; Result := TFDJSONDataSets.Create; TFDJSONDataSetsWriter.ListAdd(Result, FDQueryDepartmentNames); end;
procedure TDepartmentsClientForm.UpdateDepartmentNames(const ADataSetList: TFDJSONDataSets); begin // Update UI FDMemTableDepartments.Active := False; Assert(TFDJSONDataSetsReader.GetListCount(ADataSetList) = 1); FDMemTableDepartments.AppendData( TFDJSONDataSetsReader.GetListValue(ADataSetList, 0)); end;
Tokyo 10.2.2
TFDBatchMoveJSONWriter
https://community.embarcadero.com/blogs/entry/dataset-mapping-to-json-for-javascript-client-support-in-rad-studio-10-2-2
dataset2json
FDBatchMove1
FDBatchMoveJSONWriter1
FDBatchMoveDataSetReader1.dataset=qryPerson;
self.FDBatchMove1.Reader := self.FDBatchMoveDataSetReader1;
self.FDBatchMove1.Writer := self.FDBatchMoveJSONWriter1;
然后就得到dataset转换后的json string了.
procedure TForm3.Button3Click(Sender: TObject); var sstr: TStringStream; begin sstr := TStringStream.Create('',TEncoding.UTF8); try FDBatchMoveJSONWriter1.Stream := sstr; FDBatchMove1.Execute; Memo1.Lines.Text :=sstr.DataString; finally sstr.Free; end; end;
TJsonSerializer
序列化,反序列化
json2DataSet
http://blog.csdn.net/bzt820801/article/details/77984967
第三方优秀的库
JsonDataObjects
https://github.com/ahausladen/JsonDataObjects
XSuperObject
https://github.com/onryldz/x-superobject
数组反序列化
userList: TArray<TUser>; user: TUser; begin userList := XSuperObject.TJSON.Parse < TArray < TUser >> (Memo1.Text);
在x-superobject和TJsonSerializer在Android下都报错。2018.1.25 Tokyo 10.2.2 error。期待下一版本。
官方的例子,好好学习吧
https://community.embarcadero.com/blogs/entry/dataset-mapping-to-json-for-javascript-client-support-in-rad-studio-10-2-2
http://blog.marcocantu.com/blog/2017-december-dataset-mapping-json.html
datasetToJSON
procedure TForm5.Button1Click(Sender: TObject); var sstr: TStringStream; begin sstr := TStringStream.Create; try EmployeeTable.Active := True; FDBatchMoveJSONWriter1.Stream := sstr; FDBatchMove1.Execute; ShowMessage(sstr.DataString); finally sstr.Free; end; end;
procedure TEmployeeResource1.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var mStream: TMemoryStream; begin mStream := TMemoryStream.Create; AResponse.Body.SetStream(mStream, 'application/json', True); FDBatchMoveJSONWriter1.Stream := mStream; FDBatchMove1.Execute; end;
procedure TEmployeeResource1.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); begin FDBatchMoveJSONWriter1.JsonWriter := AResponse.Body.JsonWriter; FDBatchMove1.Execute; end;
https://community.embarcadero.com/blogs/entry/dataset-json-javascript
https://community.embarcadero.com/blogs/entry/c-builder-10-2-2-dataset-mapping-to-json-for-javascript-client-support
procedure TGroupsResource1.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var ms: TMemoryStream; begin ms := TMemoryStream.Create; EmployeeTable.Close; try EmployeeTable.Open; EmployeeTable.SaveToStream(ms, TFDStorageFormat.sfJSON); AResponse.Body.SetStream(ms, 'application/json', True); finally ms.Free; end; end;
最新封装delphi DataSetToJSON单元函数 Tokyo 10.2.2
{*******************************************************} { } { DataSet2JSON } { } { Copyright (C) 2018 KT } { } {*******************************************************} unit ktDS2JSON; interface uses Data.DB, System.Classes, FireDAC.Comp.BatchMove, FireDAC.Comp.Client, FireDAC.Comp.BatchMove.DataSet, FireDAC.Comp.BatchMove.JSON, System.SysUtils, FireDAC.Comp.DataSet; function ds2JSON(ads: TDataSet): string; implementation function ds2JSON(ads: TDataSet): string; var ssm: TStringStream; table: TFDMemTable; FDBatchMove: TFDBatchMove; FDBatchMoveDataSetReader: TFDBatchMoveDataSetReader; FDBatchMoveJSONWriter: TFDBatchMoveJSONWriter; begin ssm := TStringStream.Create('', TEncoding.UTF8); table := TFDMemTable.Create(nil); FDBatchMove := TFDBatchMove.Create(nil); table.CopyDataSet(ads, [coRestart, coAppend, coStructure]); FDBatchMoveDataSetReader := TFDBatchMoveDataSetReader.Create(nil); FDBatchMoveDataSetReader.DataSet := ads; FDBatchMoveJSONWriter := TFDBatchMoveJSONWriter.Create(nil); FDBatchMoveJSONWriter.Stream := ssm; FDBatchMove.Reader := FDBatchMoveDataSetReader; FDBatchMove.Writer := FDBatchMoveJSONWriter; FDBatchMove.Execute; Result := ssm.DataString; ssm.Free; table.Free; FDBatchMove.Free; FDBatchMoveDataSetReader.Free; FDBatchMoveJSONWriter.Free; end; end.
NULL值判断,空置判断 存在判断
if( (jo.GetValue('data').Null ) ) then begin self.errmsg := '没有数据'; MsgWarning(errmsg); exit; end;