问题
I have a similar problem to Delphi parse JSON array or array, but the answers do not fit my need.
I have this JSON:
[
{
"total": "9",
"page": "9",
"records": "99",
"rows": [
{
"id": "62316",
"titleId": "47243",
"subject": [
"000607",
"000607_",
"001727"
],
"keyFeatures": [
"AI",
"URL"
]
},
{
"id": "66",
"titleId": "47243",
"subject": [
"000607",
"000607_",
"001727"
],
"keyFeatures": [
"KK"
]
}
],
"suggestion": "90"
}
]
I would like to write all f.e. "keyFeatures" of every "id" in a memo, like this:
1: 62316 KeyFeatures: AI,URL 2: 66 KeyFeatures: KK
procedure TIFForm1.ParseJson(StrJson: string);
var
LJsonArr: TJSONArray;
LJsonArrRow: TJSONArray;
vJSONObject: TJSONObject;
vJSONPair: TJSONPair;
vJSONObjectKF: TJSONObject;
vJSONPairKF: TJSONPair;
vJasonArrRows: TJSONArray;
vJSONValue: TJSONValue;
LJSONAttribute: String;
LJSONKF_key: String;
LJSONValue: String;
i: integer;
begin
LJsonArr := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(StrJson), 0) as TJSONArray;
if LJsonArr <> nil then
try
// rows
vJasonArrRows := LJsonArr as TJSONArray;
for vJSONValue in vJasonArrRows do
begin
i := i + 1;
vJSONObject := vJSONValue as TJSONObject;
vJSONPair := vJSONObject.get('id');
LJSONAttribute := vJSONPair.JsonString.Value;
vJSONValue := vJSONPair.JsonValue.Value;
vJSONObjectKF := vJSONValue as TJSONObject;
vJSONPairKF := vJSONObject.Get('keyFeatures');
LJSONKF_key := vJSONPairKF.JsonString.Value;
// How can I here merge all keyFeatures together with , separated?
//Edit: My Serializer
rowresult.KeyFeatures := serialize(vJSONObject, 'keyFeatures');
Memo5.Lines.Add(Format('%d: %s KeyFeatures: %s', [i, rowresult.id, rowresult.keyFeatures]));
end;
finally
LJsonArr.Free;
end;
end;
Moreover, it would be handy if I could ask for the type of the JSON elements. Here is an example with keyFeatures which is again an JSON Array. But there could be more unknown named JSON keys which are also array, and these ones should also be written in the Memo. Is there a solution?
EDIT: I have solved it this way with the help from the DP Answer, look below.
function TIFForm1.serialize(MyJSONObject: TJSONObject; keystring: string): string;
var
KeyFeatures: TJSONValue;
FeatureList: TStringList;
FeatureItem: TJSONValue;
begin
KeyFeatures := (MyJSONObject as TJSONObject).GetValue(keystring);
if KeyFeatures is TJSONArray then
begin
FeatureList := TStringList.Create;
try
for FeatureItem in TJSONArray(KeyFeatures) do
FeatureList.Add(FeatureItem.Value);
Result := FeatureList.CommaText;
finally
FeatureList.Free;
end;
end
else
begin
Result := KeyFeatures.Value;
end;
end;
回答1:
A nice guy from Delphipraxis DP has provided a very sophisticated solution:
procedure TForm1.Button1Click(Sender: TObject);
var
DataBase: String;
JsonArray: TJSONArray;
ArrayElement: TJSonValue;
RowValue: TJSonValue;
RowItem: TJSonValue;
keyFeatures: TJSonValue;
FeatureItem: TJSonValue;
FeatureList: TStringlist;
Id: Integer;
Index: Integer;
begin
Memo1.Clear;
DataBase :=
'[{"total":"9","page":"9","records":"99","rows":[{"id":"62316","titleId":"47243","subject":'
+ '["000607","000607_","001727"],"keyFeatures":["AI","URL"]},{"id":"66","titleId":"47243","subject":'
+ '["000607","000607_","001727"],"keyFeatures":["KK"]}],"suggestion":"90"}]';
JsonArray := TJSonObject.ParseJSONValue(DataBase) as TJSONArray;
try
Index := 1;
for ArrayElement in JsonArray do
begin
RowValue := (ArrayElement as TJSonObject).GetValue('rows');
if RowValue is TJSONArray
then
begin
for RowItem in TJSONArray(RowValue) do
begin
RowItem.TryGetValue('id', Id);
keyFeatures := (RowItem as TJSonObject).GetValue('keyFeatures');
if keyFeatures is TJSONArray
then
begin
FeatureList := TStringlist.Create;
try
for FeatureItem in TJSONArray(keyFeatures) do
FeatureList.Add(FeatureItem.Value);
Memo1.Lines.Add(Format('%d: %d KeyFeatures: %s', [Index, Id, FeatureList.CommaText]));
finally
FeatureList.Free;
end;
end;
end;
end;
inc(Index);
end;
finally
JsonArray.Free;
end;
end;
来源:https://stackoverflow.com/questions/57536434/parsing-json-array-in-delphi