This is the sample JSON I want to be able to parse:
[
{
\"a\":{
\"username\":\"aaa\",
\"email\":\"
For new readers looking for these answers.
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(User + '.' + Field);
break;
end;
end;
end;
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.
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("b"+ '.' + "email");
break;
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
...
A working example code for the given JSON data:
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(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.
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"}]}';
When you iterate the users, you can now use GetValue with the new "user" key.
if ArrayElement.GetValue('user') = 'b' then begin
Result := ArrayElement.GetValue('email');
By giving the array a key you can now get the array with:
JsonArray := JsonValue.GetValue('users');
A working example code for the restructured JSON data:
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('users');
// iterate the array
for ArrayElement in JsonArray do begin
if ArrayElement.GetValue('user') = User then begin
Result := ArrayElement.GetValue(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.