This is the sample JSON I want to be able to parse:
[
{
\"a\":{
\"username\":\"aaa\",
\"email\":\"
Your JSON is an array of objects, so FIds
is a TJSONArray
containing TJSONObject
elements. And the a
and b
fields of those objects are themselves objects, not arrays. So FValue is TJSONArray
will always be false while enumerating that array.
Also, (FValue as TJSONArray).Items[0] as TJSONValue).Value = name
is wrong, because a JSON object contains name/value pairs, but you are ignoring the names, and you are trying to enumerate the pairs as if they are elements of an array when they are really not. If you want to enumerate an object's pairs, use the TJSONObject.Count and TJSONObject.Pairs[] property. But that is not necessary in this situation since you are looking for a specific pair by its name. TJSONObject
has a Values[] property for that very purpose.
And TJSONObject.ParseJSONValue(((FValue as TJSONArray).Items[0] as TJSONValue).ToJSON) as TJSONArray
is just plain ridiculous. There is no reason to convert an object back to a JSON string just to parse it again. It has already been parsed once, you don't need to parse it again.
And lastly, FValueInner.GetValue
is wrong, because TJSONValue
does not have a GetValue()
method, let alone one that uses Generics.
Now, with that said, try something more like this instead:
// '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
Result := '';
for FValue in Fids do
begin
if (FValue is TJSONObject) then
begin
FValueInner := TJSONObject(FValue).Values[name];
if FValueInner <> nil then
begin
if (FValueInner is TJSONObject) then
begin
FValueInner := TJSONObject(FValueInner).Values[data];
if FValueInner <> nil then
Result := FValueInner.Value;
end;
Exit;
end;
end;
end;
end;