JSON object- 如何在不知道名称的情况下遍历所有属性?

JSON object- how to iterate through all properties without knowing their names?

我有一个相当简单的 JSON:

[
    {
      "hero-img": "girl-ipad.png",
      "main-story-headline": "How to Stay Mentally Healthy During a Pandemic",
      "main-story-paragraph": "lorem ipsum",
      "main-story-button-text": "Read More"
    },
    {
      "hero-img": "painter-woman.png",
      "main-story-headline": "How to Stay Mentally Healthy During a Pandemic",
      "main-story-paragraph": "lorem ipsum",
      "main-story-button-text": "Explore More"
    },
    {
      "hero-img": "old-man.png",
      "main-story-headline": "How to Stay Mentally Healthy During a Pandemic",
      "main-story-paragraph": "lorem ipsum",
      "main-story-button-text": "Get Yours Now"
    } ]

通过使用 Delphi 10.3 Rio,我想遍历所有 属性 ,无论它们如何命名。我是这样开始的:

program JuTemplates;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.JSON, System.IOUtils, System.Types;

var
  root, OutputDir, TemplatesDir, JsonDir, jsonText: string;
  JsonFiles: TStringDynArray;
  i, j: Integer;
  JSONValue: TJSONObject;
  JSONValues: TJSONArray;
begin
  try

    try
      root := ExtractFilePath(ParamStr(0));
      OutputDir := root + 'OutputDir\';
      TemplatesDir := root + 'TemplatesDir\';
      JsonDir := root + 'JsonDir\';
      writeln('Processing: ' + JsonDir);
      JsonFiles := TDirectory.GetFiles(JsonDir);
      for i := 0  to High(JsonFiles) do
      begin
        jsonText := TFILE.ReadAllText(JsonFiles[i]);
        JSONValues := TJSONObject.ParseJSONValue(jsonText) as TJSONArray;

        for j := 0 to JSONValues.Count - 1 do
        begin
          JSONValue := JSONValues.Items[i] as TJSONObject;
          // here I should iterate through that JSONValue object
        end;
      end;
    except
      on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;
  finally
    writeln ('Press any key to continue');
    readln;
  end;
end.

要枚举 JSONObject,您可以使用如下所示的枚举器。

使用 for..in 循环(隐式枚举器)

procedure TForm1.Button1Click(Sender: TObject);
var
   JSONData       : String;
   JSONObject     : TJSONObject;
   JSONPair       : TJSONPair;
begin
   JSONData   := '... some JSON data ...';   // Place you data here
   JSONObject := TJSonObject.ParseJSONValue(JSONData) as TJSONObject;
   try
     for JSONPair in JSONObject do
         ShowMessage(Format('1) Key=%s Value=%s',
                     [JSONPair.JsonString.ToString,
                      JSONPair.JsonValue.ToString]));
   finally
     JSONObject.Free;
   end;
end;

使用经典的 for 循环:

procedure TForm1.Button1Click(Sender: TObject);
var
   JSONData       : String;
   JSONObject     : TJSONObject;
   JSONPair       : TJSONPair;
   I              : Integer;
begin
   JSONData   := '... some JSON data ...';   // Place you data here
   JSONObject := TJSonObject.ParseJSONValue(JSONData) as TJSONObject;
   try
     for I := 0 to JSONObject.Count - 1 do begin
       ShowMessage(Format('Key=%s Value=%s',
                   [JSONObject.Pairs[I].JsonString.ToString,
                    JSONObject.Pairs[I].JsonValue.ToString]));
     end;
   finally
     JSONObject.Free;
   end;
end;

使用显式枚举器和 while 循环:

procedure TForm1.Button1Click(Sender: TObject);
var
   JSONData       : String;
   JSONObject     : TJSONObject;
   JSONEnumerator : TJSONObject.TEnumerator;
   JSONPair       : TJSONPair;
begin
   JSONData   := '... some JSON data ...';   // Place you data here
   JSONObject := TJSonObject.ParseJSONValue(JSONData) as TJSONObject;
   try
     JSONEnumerator := JSONObject.GetEnumerator;
     try
       while JSONEnumerator.MoveNext do begin
         JSONPair := JSONEnumerator.Current;
         ShowMessage(Format('Key=%s Value=%s',
                     [JSONPair.JsonString.ToString,
                      JSONPair.JsonValue.ToString]));
       end;
     finally
       JSONEnumerator.Free;
     end;
   finally
     JSONObject.Free;
   end;
end;

请注意,您可能需要检查 JSONPair.JsonValue 是否有子项并使用另一个枚举器递归地枚举这些子项。