C++ Nested JSON in Unreal Engine 4

痴心易碎 提交于 2020-01-31 05:33:24

问题


I have a JSON object that I am getting from my server that looks something like this:

{
    "state":"1",
    "player1": {
        "alias":"Player Name",
        "ready":"0"
    }
}

I am able to get the JSON, parse it into a FJsonObject, and retrieve any number or string in the first level of the JSON object using this code to serialize:

TSharedPtr<FJsonObject> JsonParsed;
TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(json);
if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
    //Use JsonParsed

And this code to read strings:

FString AJSONContainer::getStringWithKey(FString key)
{
    return storedJSON->GetStringField(key);
}    

Side Note:

AJSONContainer is just an Actor class that I use to call these functions from Blueprints.


That's all fine and dandy, but when I try to read things from the second level, things don't work.

I wrote this code to get the next level down:

TSharedPtr<FJsonObject> nested = storedJSON->GetObjectField(key);

But all calls to get fields of nested return nothing.

nested->GetStringField(anotherKey); //Nothing

So, for example, with the above JSON, this:

TSharedPtr<FJsonObject> nested = storedJSON->GetObjectField("player1");
FString alias = nested->GetStringField("alias");

alias has no value when I print it to the console.


Am I doing something wrong? Why isn't the second-level JSON working?


回答1:


Don't know if you got it sorted out, but I found a pretty nasty function that works for nested objects and, also, for arrays altogether. And it gives you a USTRUCT, so you don't have to use the functions that get values by Keys (I don't like them since they're very error prone). Instead, you'll have type safety!

FJsonObjectConverter::JsonObjectStringToUStruct

Here are the docs and another question answered on UE4 AnswerHub

Basically, you create the target USTRUCT (or USTRUCTs for nested JSONs), mark all properties with UPROPERTY, so Unreal knows their names, and use this function. It will copy the values by matchmaking them. It copies even the arrays! =D

Example

I'll call the JSON FString to be deserialized Json and it's structure is like the one below. It contains a nested object and an array, to make things interesting.

{
    "nested" : {
        "id" : "654asdf",
        "name" : "The Name"
    },
    "foo" : "foobar",
    "bar_arr" : [
        { "barfoo" : "asdf" },
        { "barfoo" : "qwer" }
    ]
}

Before converting, we need to create the USTRUCTs from inside out (so we can reference inner on the outer). Remember to always use F for struct names.

USTRUCT()
struct FNested
{
    GENERATED_USTRUCT_BODY()

    UPROPERTY()
    FString id;

    UPROPERTY()
    FString name;
};

USTRUCT()
struct FBar
{
    GENERATED_USTRUCT_BODY()

    UPROPERTY()
    FString barfoo;
};

USTRUCT()
struct FJsonData
{
    GENERATED_USTRUCT_BODY()

    UPROPERTY()
    FNested nested;

    UPROPERTY()
    FString foo;

    UPROPERTY()
    TArray<FBar> bar_arr;
};

The conversion will go like this:

FJsonData JsonData;
FJsonObjectConverter::JsonObjectStringToUStruct<FJsonData>(
    Json,
    &JsonData,
    0, 0);

Now, you are able to access all the properties as in standard C++ structs. Eg., to access one of the barfoos:

FString barfoo0 = JsonData.bar_arr[0].barfoo;

I have not tested it with int and float in the JSON, but since it copies even arrays, I believe that would work also.




回答2:


    for (auto currJsonValue = JsonObject->Values.CreateConstIterator(); currJsonValue; ++currJsonValue)
    {
        // Get the key name
        const FString Name = (*currJsonValue).Key;

        // Get the value as a FJsonValue object
        TSharedPtr< FJsonValue > Value = (*currJsonValue).Value;

        TSharedPtr<FJsonObject> JsonObjectIn = Value->AsObject();
    }

The Json Object nested can be accessed by GetObjectField or the code I posted.



来源:https://stackoverflow.com/questions/30342465/c-nested-json-in-unreal-engine-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!