英文:
What is the proper way to retrieve a nested JSON field using TClientDataset in Delphi?
问题
I am using TRestClient>TRestRequest>TRestResponse>TRESTResponseDataSetAdapter
to retrieve JSON data from a Rest API. This works well and I create a TClientDataset
in memory:
// 创建一个新的内存数据集
gStaffTable := TClientDataset.Create(nil);
with gStaffTable do
begin
// 向其中添加一些字段
FieldDefs.Add('FirstName', ftString, 255, False); //0
FieldDefs.Add('MiddleName', ftString, 255, False); //1
FieldDefs.Add('LastName', ftString, 255, False); //2
// ...在这里添加其他字段 3..26
// Department 是一个嵌套字段
FieldDefs.Add('Department', ftString, 255, False); //27
// 创建数据集
CreateDataSet;
// 添加 AfterScroll 过程
AfterScroll := gStaffTableAfterScroll;
OnCalcFields := gStaffTableOnCalcFields;
IndexFieldNames := 'FullName';
Open;
FieldByName('Firstname').DisplayLabel := 'First Name';
FieldByName('MiddleName').DisplayLabel := 'Middle Name';
//.. 添加其余的显示标签
end;
I can then read my data into the fields:
ClientDataset.First;
while not ClientDataSet.EOF do
begin
with gStaffTable do
begin
try
application.ProcessMessages;
append;
FieldbyName('Firstname').AsString := ClientDataSetfirst_name.AsString;
FieldbyName('LastName').AsString := ClientDataSetlast_name.AsString;
FieldbyName('Fullname').AsString := ClientDataSetfirst_name.AsString + ' ' +
//.. 对其余字段执行相同操作
// Department 是一个嵌套字段 - 需要修改以读取部门名称
// {"name":"Finance","id":29111}
FieldbyName('Department').AsString := ClientDataSet.FieldByName('Department').AsString;
post;
except
end;
end;
application.ProcessMessages;
ClientDataSet.Next;
end;
I can then just assign the DataField to a component on the GUI (partial screen snip):
你可以从中看出我的问题所在。Department 字段是一个嵌套元素,我无法弄清楚如何访问{"name":"Finance","id":29111}
以显示 Finance。
我已尝试了解决类似问题的各种方法,但没有找到有效的解决方案。
英文:
I am using TRestClient>TRestRequest>TRestResponse>TRESTResponseDataSetAdapter
to retrieve JSON data from a Rest API. This works well and I create a TClientDataset
in memory:
// Create a new in memory dataset
gStaffTable := TClientDataset.Create(nil);
with gStaffTable do
begin
// Add some fields to it
FieldDefs.Add('FirstName', ftString, 255, False); //0
FieldDefs.Add('MiddleName', ftString, 255, False); //1
FieldDefs.Add('LastName', ftString, 255, False); //2
// ...add the other fields 3..26 here
// Department is a nested field
FieldDefs.Add('Department', ftString, 255, False); //27
// Create it
CreateDataSet;
// Add an AfterScroll procedure
AfterScroll := gStaffTableAfterScroll;
OnCalcFields := gStaffTableOnCalcFields;
IndexFieldNames := 'FullName';
Open;
FieldByName('Firstname').DisplayLabel := 'First Name';
FieldByName('MiddleName').DisplayLabel := 'Middle Name';
//.. add the rest of the displaylabels here
end;
I can then read my data into the fields:
ClientDataset.First;
while not ClientDataSet.EOF do
begin
with gStaffTable do
begin
try
application.ProcessMessages;
append;
FieldbyName('Firstname').AsString := ClientDataSetfirst_name.AsString;
FieldbyName('LastName').AsString := ClientDataSetlast_name.AsString;
FieldbyName('Fullname').AsString := ClientDataSetfirst_name.AsString + ' ' +
//.. do the same for the rest of the fields
// Department is a nested field - need to modify this to read the department name
// {"name":"Finance","id":29111}
FieldbyName('Department').AsString := ClientDataSet.FieldByName('Department').AsString;
post;
except
end;
end;
application.ProcessMessages;
ClientDataSet.Next;
end;
I can then just assign the DataField to a component on the GUI (partial screen snip):
You can see from this what my problem is. The Department field is a nested element and I cannot figure out how to access {"name":"Finance","id":29111}
to display Finance.
I have tried various resolutions to similar problems but cannot find one that works.
答案1
得分: 0
你可以使用 TJSONObject.ParseJSONValue
类函数来解析 JSON 字符串。
例如,你可以定义一个函数来提取该值:
uses
System.JSON;
function ExtractPairStringValue(const AJSONString: string; const APairName: string): string;
var
Obj: TJSONValue;
begin
Obj := TJSONObject.ParseJSONValue(AJSONString);
try
Result := Obj.GetValue<string>(APairName);
finally
Obj.Free;
end;
end;
然后,你可以像这样提取该值:
FieldByName('Department').AsString := ExtractPairStringValue(ClientDataSet.FieldByName('Department').AsString, 'name');
英文:
You can use the TJSONObject.ParseJSONValue
class function for parsing the JSON string.
For example, you can define a function to extract the value:
uses
System.JSON;
function ExtractPairStringValue(const AJSONString : string; const APairName : string) : string;
var
Obj : TJSONValue;
begin
Obj := TJSONObject.ParseJSONValue(AJSONString);
try
Result := Obj.GetValue<string>(APairName);
finally
Obj.Free;
end;
end;
Then you'll be able to extract the value like this:
FieldByName('Department').AsString := ExtractPairStringValue(ClientDataSet.FieldByName('Department').AsString, 'name');
答案2
得分: 0
你可以创建一个嵌套的 ClientDataSet 来处理数据绑定。以下是我的示例:
var
gStaffTable: TClientDataSet;
begin
gStaffTable := ClientDataSet1;
with gStaffTable do
begin
// 添加字段
FieldDefs.Add('FirstName', ftString, 255, False); // 0
FieldDefs.Add('MiddleName', ftString, 255, False); // 1
FieldDefs.Add('LastName', ftString, 255, False); // 2
// 为 'Department' 结构定义一个嵌套字段
with FieldDefs.AddFieldDef do
begin
Name := 'Department';
DataType := ftDataSet;
ChildDefs.Add('Name', ftString, 255, False);
ChildDefs.Add('id', ftInteger);
end;
end;
// 创建数据集
gStaffTable.CreateDataSet;
end;
在这段代码中,我们首先定义了数据集的主要字段。然后,我们为 'Department' 结构定义了一个嵌套字段,其中包含 'Name' 和 'id'。在定义字段结构后,我们调用 CreateDataSet 来最终确定数据集的结构。
现在,你有一个与你的 JSON 结构对应的嵌套 ClientDataSet,你可以使用它来绑定你的数据。请注意,你需要手动处理从 JSON 到数据集的数据赋值,或通过其他数据绑定机制来完成。
英文:
You can create a nested ClientDataSet to handle DataBinding. Here's my example:
var
gStaffTable: TClientDataSet;
begin
gStaffTable := ClientDataSet1;
with gStaffTable do
begin
// Add fields
FieldDefs.Add('FirstName', ftString, 255, False); //0
FieldDefs.Add('MiddleName', ftString, 255, False); //1
FieldDefs.Add('LastName', ftString, 255, False); //2
// Define a nested field for the 'Department' structure
with FieldDefs.AddFieldDef do
begin
Name := 'Department';
DataType := ftDataSet;
ChildDefs.Add('Name', ftString, 255, False);
ChildDefs.Add('id', ftInteger);
end;
end;
// Create the DataSet
gStaffTable.CreateDataSet;
end;
In this code, we first define the main fields of the dataset. Then, we define a nested field for the 'Department' structure, which contains a 'Name' and an 'id'. After defining the structure of our fields, we call CreateDataSet to finalize the dataset structure.
Now, you have a nested ClientDataSet that corresponds to your JSON structure, and you can use this to bind your data. Please note that you will need to handle the data assignment from the JSON to the dataset manually or via another DataBinding mechanism.
答案3
得分: -1
Add another field to dataset "DepartmentName" then set a TField.OnGetText event on it.
procedure GetDepartmentNameValue should extract data from JSON
If you want to set value to finance, create a procedure to do it
procedure TForm1.FieldOnGetText(Sender: TField; var Text: string;
DisplayText: Boolean);
begin
Text := GetDepartmentNameValue(Sender);
end;
procedure TForm1.FieldOnSetText(Sender: TField; var Text: string; DisplayText: Boolean);
begin
SetDepartmentNameValue(sender, Text);
end;
英文:
Add another field to dataset "DepartmentName" then set an TField.OnGetText event on him.
procedure GetDepartmentNameValue should extract data from JSON
If you want to set value to finance make procedure to do it
procedure TForm1.FieldOnGetText(Sender: TField; var Text: string;
DisplayText: Boolean);
begin
Text := GetDepartmentNameValue(Sender);
end;
procedure TForm1.FieldOnSetText(Sender: TField; var Text: string; DisplayText: Boolean);
begin
SetDepartmentNameValue(sender, Text);
end;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论