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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Need help parsing Json

Discussion in 'Scripting' started by Thibault-Potier, Oct 10, 2019.

  1. Thibault-Potier

    Thibault-Potier

    Joined:
    Apr 10, 2015
    Posts:
    206
    Hi
    I want to parse some JSon but i'm struggling to understand how it can work. Here is my Json :

    Code (csharp):
    1.  
    2. {
    3.    "full_network":{
    4.       "Fixed Nodes":{
    5.          "babe":1,
    6.          "hrwx":0,
    7.          "dro0":1,
    8.          "user":1,
    9.          "bd9b":1,
    10.          "b74d":1
    11.       },
    12.       "Network":[
    13.          "[bd9b-user-{'bd9b': 1, 'user': 1}]",
    14.          "[b74d-bd9b-{'bd9b': 100, 'b74d': 100}]",
    15.          "[bd9b-dro0-{'dro0': 1, 'bd9b': 1}]",
    16.          "[dro0-user-{'dro0': 1, 'user': 1}]",
    17.          "[b74d-hrwx-{'b74d': 1, 'hrwx': 1}]"
    18.       ],
    19.       "Links":[
    20.          [
    21.             "bd9b",
    22.             "user",
    23.             1
    24.          ],
    25.          [
    26.             "b74d",
    27.             "bd9b",
    28.             100
    29.          ],
    30.          [
    31.             "bd9b",
    32.             "dro0",
    33.             1
    34.          ],
    35.          [
    36.             "dro0",
    37.             "user",
    38.             1
    39.          ],
    40.          [
    41.             "b74d",
    42.             "hrwx",
    43.             1
    44.          ]
    45.       ]
    46.    },
    47.    "command":"get_full_network",
    48.    "error_description":"",
    49.    "request_id":"45"
    50. }
    51.  
    What i'm interested in is the "Links" array. Final purpose is to create a sort of graph (or tree) showing nodes name and links.
    I would like to extract those in a list of object like this :

    Code (csharp):
    1.  
    2. [Serializable]
    3. public class Link
    4. {
    5.     public string peerA;
    6.     public string peerB;
    7.     public int weight;
    8. }
    9.  
    When i receive the json message :
    > i don't know the number of links the is in the json message
    > i don't know the nodes name
    I basically have no idea on how to extract those data :/

    Here is my lame attempt :

    Code (csharp):
    1.  
    2. public void handle_fullNetwork()
    3.     {
    4.         string test = "{\"full_network\": {\"Fixed Nodes\": {\"babe\": 1, \"hrwx\": 0, \"dro0\": 1, \"user\": 1, \"bd9b\": 1, \"b74d\": 1}, \"Network\": [\"[bd9b-user-{'bd9b': 1, 'user': 1}]\", \"[b74d-bd9b-{'bd9b': 100, 'b74d': 100}]\", \"[bd9b-dro0-{'dro0': 1, 'bd9b': 1}]\", \"[dro0-user-{'dro0': 1, 'user': 1}]\", \"[b74d-hrwx-{'b74d': 1, 'hrwx': 1}]\"], \"Links\": [[\"bd9b\", \"user\", 1], [\"b74d\", \"bd9b\", 100], [\"bd9b\", \"dro0\", 1], [\"dro0\", \"user\", 1], [\"b74d\", \"hrwx\", 1]]}, \"command\": \"get_full_network\", \"error_description\": \"\", \"request_id\": \"45\"}";
    5.        
    6.         FullNetwork item = JsonUtility.FromJson<FullNetwork>(test);
    7.  
    8.         Debug.Log(item.Links.Length); // throw an error
    9.  
    10.     }
    11.  
    12. [Serializable]
    13. public class Link
    14. {
    15.     public string peerA;
    16.     public string peerB;
    17.     public int weight;
    18. }
    19. [Serializable]
    20. public class FullNetwork
    21. {
    22.     public Link[] Links;
    23. }
    24.  
    If someone is familiar with Json parsing in unity i would love to have some help :D
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    Do you have any control over the incoming JSON? If so, you'll want to make the links look more like this:
    Code (csharp):
    1.  
    2.       "Links":[
    3.          {
    4.             "peerA" : "bd9b",
    5.             "peerB" : "user",
    6.             "weight" : 1
    7.          },
    If you can't, then you'll have to treat each link as an untyped array (that is, object[] ) and typecast link[0], link[1], and link[2] into string/string/int respectively when you want to use them, which will get complicated.
     
  3. Thibault-Potier

    Thibault-Potier

    Joined:
    Apr 10, 2015
    Posts:
    206
    I have no control :/ I will try to play around with untyped object i guess
     
  4. Thibault-Potier

    Thibault-Potier

    Joined:
    Apr 10, 2015
    Posts:
    206
    i made change to :

    Code (csharp):
    1.  
    2. [Serializable]
    3. public class FullNetwork
    4. {
    5.     public object[] Links;
    6. }
    7.  
    And tryed :

    Code (csharp):
    1.  
    2.         FullNetwork item = JsonUtility.FromJson<FullNetwork>(test);
    3.         Debug.Log(item.Links);
    4.  
    Item.links is still returning null. What am i doing wrong ?
     
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    OK, looking a little deeper into your code now, and there's several things that need to be taken care of.

    First, you need to include the full hierarchy in your class structure, including the exact names. In this case you need an outer class first which is what you give to JsonUtility.FromJson:
    (I'm including even the ones you didn't say you needed just so the data structure is clear, and you never know when you'll need it)
    Code (csharp):
    1. public class FullJsonFile {
    2. public FullNetwork full_network;
    3. public string command;
    4. public string error_description;
    5. public string request_id;
    6. }
    Then FullNetwork needs the objects that that item contains:
    Code (csharp):
    1. public class FullNetwork {
    2. //public Dictionary<string, int> Fixed Nodes; //this won't compile and I don't know if there's a workaround for JSON names that include spaces. This JSON file is just really bad for this application. If you need this at some point you might try FixedNodes or Fixed_Nodes and see if those work. Fortunately if you don't need it we can just comment it out.
    3. public List<string> Network;
    4. public List<List<object>> Links; //decided to use List instead of object[] because the syntax is a little more clear IMO
    5. }
    And then we run into a new problem: JsonUtility.FromJson doesn't support lists or arrays (or dictionaries). It's dumb and annoying and all that. The good news is that LitJson does support lists, and once LitJson is added to your project, its JsonMapper.ToObject can be directly substituted in for JsonUtility.FromJson with no other syntax changes and it'll just work, so none of our prior work is wasted.

    Now, you should be able to do this:
    Code (csharp):
    1. FullJsonFile jsonObj = JsonMapper.ToObject<FullJsonFile>(test);
    2. foreach(List<object> thisLink in jsonObj.full_network.Links) {
    3. Debug.Log($"peerA is {thisLink[0]}, peerB is {thisLink[1]}, weight is {thisLink[2]}");
    4. }
    (code is untested of course so no guarantees it'll work first try)
     
    Thibault-Potier likes this.
  6. Thibault-Potier

    Thibault-Potier

    Joined:
    Apr 10, 2015
    Posts:
    206
    Wow. And that actually worked on first try ! Thank you so much