Parsing JSON Array in Delphi

亡梦爱人 提交于 2021-02-05 12:26:22

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!