Download

JSON help with complex structures

Hello community!

I was already able to handle 1 dimensional JSON queries but it got to complicated.
I looked trough the internet but nothing helped me handling this json query:


{  
   "bSuccesful":2,
   "Servers":{  
      "s1":{  
         "Map":"DefaultMap",
         "Password":"kappa"
      },
      "s2":{  
         "Map":"DefaultMap",
         "Password":"kappa"
      }
   }
}

In pseudo code I need the follwing:


For(Server in Servers)
{
    Servername = Server
    Map = Server.GetString("Map")
    Password = Server.GetString("Password")
}

So basically for all “Servers” I need the String if its name, “s1” in the example and the values of “s1”, in the example “map” and “password”.

I tried everything I found in the net and was able to come up with so I would really apprechiate if you could help me (;

Thanks in advance.

IMHO, your json looks a little bit strange. It would be much easier to parse it if you made array of objects and not object with objects inside. Something like this:



{  
   "bSuccesful":2,
   "Servers":  
     {  
	 "Name":"s1",
         "Map":"DefaultMap",
         "Password":"kappa"
      },
      {  
	 "Name":"s2",
         "Map":"DefaultMap",
         "Password":"kappa"
      }
   ]
}


Now you just need the following code to get all info:



auto entity = JsonObject->AsObject();
TArray< TSharedPtr< FJsonValue > > servers;
servers = entity->GetArrayField("Servers");
for (int i = 0; i < servers.Num(); i++)
{
	auto server = servers*->AsObject();
	FString serverName = server->GetStringField("Name");
}


JsonObject comes from


FJsonSerializer::Deserialize(Reader, JsonObject);

Hope this helps :slight_smile:

Had the same issue a while back. If you know the JSON structure being returned, use FJsonObjectConverter::JsonObjectStringToUStruct<FJsonData>
More here: http://stackoverflow.com/questions/30342465/c-nested-json-in-unreal-engine-4

There’s not much point in using JsonObjectStringToUStruct

To get single field:

FJsonObject::GetStringField, GetNumberField, etc.

To get array field:
FJsonValue::AsArray()
or
FJsonObject::TryGetArrayField()

To get nested object:

First get FJsonValue (using FJsonObject::GetField()), then call FJsonValue::AsObject().

So the only trick to get nested value is to first get FJsonValue, then convert it corresponding type, using AsArray() or AsObject().



typedef TSharedPtr<FJsonValue> JsonValPtr;
typedef TArray<JsonValPtr> JsonValPtrArray;

.......

const JsonValPtrArray *servers;
if (rootNode->TryGetArrayField(FString("Servers"), servers)){
     for (auto curServer: *servers){
          auto serverObj = curServer->AsObject();
          if (!serverObj.IsValid())
              continue;
          auto mapName = serverObj->GetStringField(FString("Map"));
     }
}