Delphi解析JSON数组或数组 [英] Delphi parse JSON array or array

查看:197
本文介绍了Delphi解析JSON数组或数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我希望能够解析的示例JSON:

This is the sample JSON I want to be able to parse:

[
  {
    "a":{
      "username":"aaa",
      "email":"aaa@gmail.com"
    }
  },
  {
    "b":{
      "username":"bbb",
      "email":"bbb@gmail.com"
    }
  }
]

我需要对getData('b', 'email')的调用必须输出bbb@gmail.com

I need that a call to getData('b', 'email') must output bbb@gmail.com!

我真的很努力地了解如何使用System.JSON单元,但是我找不到解决方案!我希望能够编写一个从上述JSON结构中提取特定数据的函数.到目前为止,这是我的代码.在类构造函数中,我有:

I am really struggling to understand how to use the System.JSON unit, but I can't get the solution! I want to be able to write a function that extracts a particular data from the above kind of JSON structure. This is my code so far. In the class constructor I have:

var
  FIds: TJSONArray;
begin
  FIds := TJSONObject.ParseJSONValue({json string here}) as TJSONArray;
end;

然后,在必须返回数据的函数中,我这样写:

Then, inside the function that must return the data, I have written this:

// 'name' can be 'a' or 'b'  | 'data' can be 'username' or 'email'
function TTest.getData(const name, data: string): string;
var
  FValue, FValueInner: TJSONValue;
begin
  for FValue in Fids do
  begin
    if (FValue is TJSONArray) then
    begin
      //Here I am sure that I have a TJSONArray (which can be 'a' or 'b' from above)
    end;
  end;
end;

根据上面的内容,我必须检查name的值并确定是否必须访问ab中的数据.然后,一旦选择了正确的JSON数组ab,就必须选择是否要显示usernameemail字段(在data变量中指定).

According to what I have written above, I have to check the value of name and decide if I have to access the data inside a or b. Then, once I have picked the correct JSON array a or b, I have to select if I want to display the username or the email field (which is specified inside the data variable).

我该怎么做?

这是我最近的尝试,但我真的不知道该怎么办:

This is my latest attempt but I really can't understand what to do:

... same code above ...

if (FValue is TJSONArray) then
begin
  //here I want to check if the current array is a or b
  if ((FValue as TJSONArray).Items[0] as TJSONValue).Value = name then
  begin
    Farr := TJSONObject.ParseJSONValue(((FValue as TJSONArray).Items[0] as TJSONValue).ToJSON) as TJSONArray;
    try
      //here I want to get the data inside username or email
      for FValueInner in Farr do
        Result := FValueInner.GetValue<string>(data);
    finally
      Farr.Free;
    end;
  end;
end;

Farr: TJSONArray;FValueInner: TJSONValue;

推荐答案

面向寻求这些答案的新读者.

For new readers looking for these answers.

该功能如何?如果重新构建JSON数据,甚至更简单?

How about this function, or even simpler if you restructure the JSON data?

function getData(JsonString: String; User: String; Field: String): String;
var
  JSonValue: TJSonValue;
  JsonArray: TJSONArray;
  ArrayElement: TJSonValue;
  FoundValue: TJSonValue;
begin
  Result :='';

  // create TJSonObject from string
  JsonValue := TJSonObject.ParseJSONValue(JsonString);

  // get the array
  JsonArray := JsonValue as TJSONArray;

  // iterate the array
  for ArrayElement in JsonArray do begin
      FoundValue := ArrayElement.FindValue(User);
      if FoundValue <> nil then begin
        Result := ArrayElement.GetValue<string>(User + '.' + Field);
        break;
      end;
  end;
end;

上面的示例JSON代码的问题在于,它使用用户名"a""b"作为用户数据的 JSON键 {key:data}.这样,您就无法在数据搜索中使用GetValue("a").以不同的方式构造JSON数据使搜索过程更加容易.稍后,我将举一个例子.

The problem with the sample JSON code above is that it uses the users' names "a" "b" as a JSON-key {key:data} for the users' data. In this way you can't use GetValue("a") in your search for data. Structuring your JSON data differently makes the search process a lot easier. I will later on give an example of this.

处理给定JSON数据的一种方法是使用 FindValue ,因此您可以检查是否具有 key 的字段strong>存在"a"或"b".

A way to handle the given JSON data is by using FindValue so you can check if a field with key "a" or "b" exists.

FoundValue := ArrayElement.FindValue("b");
if FoundValue <> nil then begin
    Result := ArrayElement.GetValue<string>("b"+ '.' + "email");
    break;

关于"解析JSON数组"问题:将数据作为TJSonObject加载后,您可以将数据更改为TJSONArray并迭代元素.

About the 'parsing a JSON array' question: After the data is loaded as a TJSonObject you can change the data into a TJSONArray and iterate the elements.

  JsonValue := TJSonObject.ParseJSONValue(JsonString);  
  JsonArray := JsonValue as TJSONArray;
  for ArrayElement in JsonArray do begin
    ...

给定JSON数据的有效示例代码:

unit JsonArray1;

interface

uses System.JSON;

function getData2(JsonString: String; User: String; Field: String): String;
procedure Test1();

implementation

function getData2(JsonString: String; User: String; Field: String): String;
var
  JSonValue: TJSonValue;
  JsonArray: TJSONArray;
  ArrayElement: TJSonValue;
  FoundValue: TJSonValue;
begin
  Result :='';

  // create TJSonObject from string
  JsonValue := TJSonObject.ParseJSONValue(JsonString);

  // get the array
  JsonArray := JsonValue as TJSONArray;

  // iterate the array
  for ArrayElement in JsonArray do begin
      FoundValue := ArrayElement.FindValue(User);
      if FoundValue <> nil then begin
        Result := ArrayElement.GetValue<string>(User + '.' + Field);
        break;
      end;
  end;
end;

procedure Test1();
var
  DataBase: String;
  EmailAddress : String;
  Username: String;
begin
  DataBase := '[  {"a" : {"username":"aaa","email":"aaa@gmail.com"}},' +
                 '{"b" : {"username":"bbb","email":"bbb@gmail.com"}}  ]';

  EmailAddress := getData2(DataBase, 'b', 'email');
  Username := getData2(DataBase, 'a', 'username');

end;

end.

如前所述,使用适当的键重组JSON数据可使代码查找数据更加简单.由于用户数据"a":{},"b":{}之间存在一对一的关系,因此很容易引入用户"密钥.另外,在数组中添加用户"键也会导致所有数据都具有键.

As already mentioned, restructuring the JSON data with proper keys makes the code to find data more simple. Because there is a 1 on 1 relation between the users' data "a":{}, "b":{} it's easy to introduce a 'user' key. Also adding a 'users' key to the array results in all data having keys.

  '{"users" : [{ "user":"a", "username":"aaa","email":"aaa@gmail.com"},' +
              '{ "user":"b", "username":"bbb","email":"bbb@gmail.com"}]}';

迭代用户时,现在可以将GetValue与新的用户"键一起使用.

When you iterate the users, you can now use GetValue with the new "user" key.

  if ArrayElement.GetValue<String>('user') = 'b' then begin
    Result := ArrayElement.GetValue<String>('email');

通过为数组提供键,您现在可以使用以下命令获取数组:

By giving the array a key you can now get the array with:

JsonArray := JsonValue.GetValue<TJSONArray>('users');

重构后的JSON数据的工作示例代码:

unit JsonArray2;

interface

uses System.JSON;

function getData2(JsonString: String; User: String; Field: String): String;
procedure Test2();

implementation

function getData2(JsonString: String; User: String; Field: String): String;
var
  JSonValue: TJSonValue;
  JsonArray: TJSONArray;
  ArrayElement: TJSonValue;
  FoundValue: TJSonValue;
begin
  Result :='';

  // create TJSonObject from string
  JsonValue := TJSonObject.ParseJSONValue(JsonString);

  // get the array
  JsonArray := JsonValue.GetValue<TJSONArray>('users');

  // iterate the array
  for ArrayElement in JsonArray do begin
      if ArrayElement.GetValue<String>('user') = User then begin
        Result := ArrayElement.GetValue<String>(Field);
        break;
      end;
  end;
end;

procedure Test2();
var
  DataBase: String;
  EmailAddress : String;
  Username: String;
begin
  DataBase := '{"users" : [{ "user":"a", "username":"aaa","email":"aaa@gmail.com"},' +
                          '{ "user":"b", "username":"bbb","email":"bbb@gmail.com"}]}';

  EmailAddress := getData2(DataBase, 'b', 'email');
  Username := getData2(DataBase, 'a', 'username');

end;

end.

这篇关于Delphi解析JSON数组或数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆