Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Parse complex json

Discussion in 'Scripting' started by sartemd174, Mar 14, 2018.

  1. sartemd174

    sartemd174

    Joined:
    Mar 14, 2018
    Posts:
    6
    Hello, i checked a lot of example of using JsonUtility but i can't figure out what to do in my case.
    I have this json:


    {
    "success":1,
    "errors":[],
    "data":
    {
    "question_name":"First question",
    "answers":
    {
    "a_0":{"name":"120","correct":"0"},
    "a_1":{"name":"90","correct":"0"},
    "a_2":{"name":"85","correct":"0"},
    "a_3":{"name":"110","correct":"1"}
    }
    "question_name":"Second question",
    "answers":
    {
    "a_0":{"name":"Big","correct":"0"},
    "a_1":{"name":"Small","correct":"0"},
    "a_2":{"name":"Thin","correct":"0"},
    "a_3":{"name":"Thick","correct":"1"}
    }
    }
    }


    As you can see, i have question array inside data field, questions array also has answers array (answer is array too with 2 fields - name,correct). How can i parse this data?
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,378
    First, use code tags:
    https://forum.unity.com/threads/using-code-tags-properly.143875/

    Next.

    JsonUtility only supports parsing json to an existing class structure. If you want to be able to loose parse it into a lookup table, or dictionary. Use something like Json.NET:
    https://www.newtonsoft.com/json

    There are also more compact versions as well. Like this one on unify:
    http://wiki.unity3d.com/index.php/SimpleJSON

    ...

    If you want to use JsonUtility, like I said, you must create the class structure it would parse into.

    First off... you json is malformed...

    If "data" is supposed to be an array, and "answers" is supposed to be an array. You may also want to change those bool responses from 1/0 to true/false... json supports bools. It should look like this:
    Code (csharp):
    1.  
    2. {
    3.     "success":true,
    4.     "errors":[],
    5.     "data":
    6.     [
    7.         {
    8.             "question_name":"First question",
    9.             "answers":
    10.             [
    11.                 {"name":"120","correct":false},
    12.                 {"name":"90","correct":false},
    13.                 {"name":"85","correct":false},
    14.                 {"name":"110","correct":true}
    15.             ]
    16.         },
    17.         {
    18.             "question_name":"Second question",
    19.             "answers":
    20.             [
    21.                 {"name":"Big","correct":false},
    22.                 {"name":"Small","correct":false},
    23.                 {"name":"Thin","correct":false},
    24.                 {"name":"Thick","correct":true}
    25.             ]
    26.         }
    27.     ]
    28. }
    29.  
    And you might shape your class structure like this:
    Code (csharp):
    1.  
    2. [System.Serializable]
    3. public class Response
    4. {
    5.     public bool success;
    6.     public ?[] errors; //your example json doesn't give a description of what might appear here
    7.     public QuestionData[] data;
    8. }
    9.  
    10. [System.Serializable]
    11. public class QuestionData
    12. {
    13.    
    14.     public string question_name;
    15.     public AnswerData[] answers;
    16.    
    17. }
    18.  
    19. [System.Serializable]
    20. public class AnswerData
    21. {
    22.     public string name;
    23.     public bool correct;
    24. }
    25.  
     
    Pauleta and sartemd174 like this.
  3. sartemd174

    sartemd174

    Joined:
    Mar 14, 2018
    Posts:
    6
    Thank you very much. One more thing, how can i access these fields?

    For example, i need "First question". Do i need to manually create custom 'get' method in response class?

    Code (CSharp):
    1.         string json = getJsonfromApi();
    2.         Response response = JsonUtility.FromJson<Response>(json);
    I'm really sorry for asking this basic question, but this is my first experience with C#/Unity.
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,378
    Code (csharp):
    1. var question1 = response.data[0];
    2. Debug.Log(question1.question_name);
     
    jerry2157 and sartemd174 like this.
  5. AryaTcs

    AryaTcs

    Joined:
    Jun 21, 2019
    Posts:
    8
    can someone please help me to parse the json and get the values for below

    {
    "horl": [
    {
    "booster": [
    "land",
    "marketing","22"},
    {
    "booster": [
    "land",
    "marketing",
    [
    "rare",
    "mythic rare"
    ]
    ]
    }
    ]
    }
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,599
    What code do you have? We can't write your program. If you need a properly-shaped JSON container, use something like json2csharp to generate starting boilerplate code.
     
  7. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,505
    Well, when you use jsonlint.com, paste your json text and click validate you will notice that your text is not valid json. You're missing a closing square bracket after your "22". Though you json structure contains a lot mixed data which isn't supported by most serializers / deserializers. The booster array of your first object contains 3 string values. However in your second object it contains two strings and one nested array. Nested arrays aren't supported by Unity's JsonUtility at all. Other serializers might support them, but having mixed data types in a single array is generally an issue. In this case you would need to work with an untyped "object" array and you need a lot of casting and type checking.

    My SimpleJSON parser can parse any valid json text and just provides a convenient way to read the parsed data. Though I wouldn't recommend a json structure like what you have at the moment (of course assuming you actually fixed the missing bracket).
     
  8. AryaTcs

    AryaTcs

    Joined:
    Jun 21, 2019
    Posts:
    8
    hi thank you for your response.

    I understand that it has a workaround to parse json which contains mixed data types in single array.

    can you please help me to write a code for this particular json below

    thank you in advance
    Code (CSharp):
    1. {
    2.     "input": {
    3.          "title": {
    4.              "row": [
    5.                 {
    6.                     "game": [
    7.                         "sfg",
    8.                         "4"
    9.                     ]
    10.                 },
    11.                 {
    12.                     "game": [
    13.                         "4",
    14.                         {
    15.                             "output": "fg",
    16.                             "player": {
    17.                                 "id": "ff",
    18.                                 "player2": {
    19.                                     "id":"cv"
    20.                                 }
    21.                             }
    22.                         }
    23.                     ]
    24.                 }
    25.             ]
    26.         }
    27.     }
    28. }
     
  9. Serinx

    Serinx

    Joined:
    Mar 31, 2014
    Posts:
    785
    @AryaTcs As @Kurt-Dekker mentioned earlier, you can generate C# from JSON using https://json2csharp.com/

    I copy-pasted your JSON in there and this is what it gave me:


    Code (CSharp):
    1. // Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
    2.     public class Row    {
    3.         public List<object> game { get; set; }
    4.  
    5.     }
    6.  
    7.     public class Title    {
    8.         public List<Row> row { get; set; }
    9.  
    10.     }
    11.  
    12.     public class Input    {
    13.         public Title title { get; set; }
    14.  
    15.     }
    16.  
    17.     public class Root    {
    18.         public Input input { get; set; }
    19.  
    20.     }
    21.  
    22.  
     
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,505
    Well with SimpleJSON you can simply do

    Code (CSharp):
    1. JSONNode root = JSON.Parse(yourJSONText);
    and now you can directly access any information you want In your example if you want to read the player id "ff" you can directly do this

    Code (CSharp):
    1. JSONNode player = root["input"]["title"]["row"][1]["game"][1]["player"];
    2. string playerID = player["id"].Value;
    Likewise if you want to read the "sfg" you can do

    Code (CSharp):
    1. string text = root["input"]["title"]["row"][0]["game"][0].Value;
    That's how you can access any data that has been parsed. However it's completely unclear how you want to use it, what information in those mixed arrays might change or how you want to identify the different mixed types. JSON is just a data format, nothing else. What you do with it or what it means is completely up for your own interpretation.
     
    DevSpur and Kurt-Dekker like this.
  11. SALMI55

    SALMI55

    Joined:
    Oct 20, 2020
    Posts:
    2
    I have this json in my console unity, i want to access position, what's wrong with my code please ?
    i have done this :
    JSONNode position = root["streams"][0]["objects"][0]["position"];
    and i converted the sting x to float lke this:

    string x = position["x"].Value;
    string y = position["y"].Value;
    string z = position["z"].Value;

    X = float.Parse(x);
    Y= float.Parse(y);
    z= float.Parse(z);


    Vector3 newPosition = new Vector3(X, Y, Z);
    gameObject.transform.localPosition = newPosition;

    but i didn't get the value of x on the vector in the inspector
    {
    "cmd": "data",
    "streams": [
    {
    "name": "usb",
    "objects": [
    {
    "name": "face",
    "mono": {
    "position": {
    "x": "0.030760",
    "y": "0.071577",
    "z": "0.928508"
    }
    }
    }
    ]
    }
    ]
    }
     
    Last edited: Jun 4, 2021
  12. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,505
    Well, first of all, please use the code tags whenever you want to post code or any other formatted text. Your code and json is really hard to read.

    Apart from that, why do you manually parsing the float values? If you use the Unity extension file of the SimpleJSON framework, you should be able to just do:

    Code (CSharp):
    1. Vector3 position = root["streams"][0]["objects"][0]["position"];
    Please note that your json actually contains the vector fields as strings. That's not really an issue because SimpleJSON can automatically convert between types. So even when you don't have the Unity extension file, you can still just do:

    Code (CSharp):
    1. JSONNode position = root["streams"][0]["objects"][0]["position"];
    2. Vector3 pos = new Vector3(position["x"].AsFloat, position["y"].AsFloat, position["z"].AsFloat);
    3.  
    Note that
    float.Parse
    by default uses your local culture setting. So if your (or your customers) PC / device uses the "comma" as decimal point instead of the "dot" your code would break. That's why we have the invariant culture.
     
  13. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,599
    Please don't post to three-year-old threads unrelated to your specific problem. It's against forum rules.

    Instead, make your own post... it's FREE!

    When you post, remember that NOBODY here can read your mind. You need to communicate everything clearly.

    How to report your problem productively in the Unity3D forums:

    http://plbm.com/?p=220

    How to understand compiler and other errors and even fix them yourself:

    https://forum.unity.com/threads/ass...3-syntax-error-expected.1039702/#post-6730855

    If you post a code snippet, ALWAYS USE CODE TAGS:

    How to use code tags: https://forum.unity.com/threads/using-code-tags-properly.143875/

    Also, consider this:
     
    Last edited: Jun 7, 2021
  14. SALMI55

    SALMI55

    Joined:
    Oct 20, 2020
    Posts:
    2
    thank you @Bunny83 fot your response and @Kurt-Dekker. Sorry, it's the first time i post here. Next time i will use the code tags
     
    EyeUnitedEmCee likes this.