解析 Firebase JSON 数组

Parse Firebase JSON array

我需要解析来自 Firebase 数据库的以下 JSON 响应。在这个 JSON 示例中,有 2 个文档 qouap915p3vl。两个文档都有多个字段。我想将每个文档中的所有字段字符串合并到一行。

{
  "documents": [
    {
      "name": "projects/..",
      "fields": {
        "qouap9": {
          "stringValue": "A1:Hello;"
        },
        "5": {
          "stringValue": "A9:..."
        },
        "6": {
          "stringValue": "A10:..."
        }
      },
      "createTime": "2020-08-08T20:44:2",
      "updateTime": "2020-08-08T20:44:3"
    },
    {
      "name": "projects/..",
      "fields": {
        "15p3vl": {
          "stringValue": "A2:2020;"
        },
        "2": {
          "stringValue": "A6:..."
        },
        "t0w4yj": {
          "stringValue": "A4:2020;"
        },
        "1": {
          "stringValue": "A5:..."
        }
      },
      "createTime": "2020-10-20T06:58:2",
      "updateTime": "2020-10-20T06:58:2"
    }
  ]
}

我想要这样的结果:

A1:Hello; A9:... A10:...

A2:2020; A6:... A4:2020; A5:...

上次没解释清楚,再试一次

implementation

uses
  System.JSON;

procedure DoSomeJSONStuff(const jsonstr: string);
var
  jo, fields: TJSONObject;
  ja: TJSONArray;
  jv: TJSONValue;
  i: integer;
  desiredstr: string;
begin

  // 1.
  jo := TJSONObject.ParseJSONValue(jsonstr) as TJSONObject;
  if (jo <> nil) then begin
    try

      // 2.
      ja := jo.GetValue('documents') as TJSONArray;

      // 3.
      for jv in ja do begin
        fields := (jv as TJSONObject).GetValue('fields') as TJSONObject;
        desiredstr := '';

        // 4.
        for i := 0 to fields.Count - 1 do begin
          desiredstr := desiredstr + (fields.Pairs[i].JsonValue as TJSONObject).GetValue('stringValue').Value;
        end;
        ShowMessage(desiredstr);
      end;
    finally

      // 5.
      jo.Free;
    end;
  end;
end;
  1. jsonstr 中是您的 JSON 作为字符串。使用 TJSONObject.ParseJSONValue 你可以解析你的 JSON 并在没有失败的情况下得到一个 TJSONValue 。否则值为 nil,因此检查 variable <> nil。由于 TJSONObject 派生自 TJSONValue,在这种情况下可以简单地显式转换。几乎所有内容都源自 Delphi JSON 框架中的 TJSONValue。如果你想检查 TJSONValue 是否真的是你想要的 JSON 容器,你可以这样做:

    var
     jv: TJSONValue;
     jo: TJSONObject;
    begin
      jv := TJSONObject.ParseJSONValue(jsonstr);
      if jv is TJSONObject then begin
        jo := (jv as TJSONObject);
        // code here
      end else
        raise Exception.Create('Unexpected container - expected: TJSONObject');
    
  2. 下一步是在 JSON 中获取 documents。它的值是一个数组。如果您不确定结构,可以使用 TryGetValue 而不是 GetValue。您可以再次检查返回值是否实际上是 TJSONArrayvariable is TJSONArray。我假设你的结构总是一样的。

  3. 现在我们用一个简单的 for in 循环遍历数组。

  4. 由于您的 fields 的元素名称没有“静态”名称,我们按计数遍历字段。我们得到 TJSONValue 并将其转换为 TJSONObject。对于 TJSONObject,我们得到带有 GetValue('stringValue').ValuestringValue 并将其连接到 desirestr 变量。

  5. 只要您只引用它,您只需释放您的“主要”variable/container。其他一切都只是一个 Pointer.

编辑 #1:关于 nil 的提示。编辑 #2:释放内存。