[JSON] How to parse array

Good morning all I have a problem if someone can give me a lead or help me. I’m looking to parse a matrix (the json coming from using a python script), my json looks like this:

Or, I don’t know how to parse my matrixes?

idk. The json appears valid, but you showed no code on what you were doing to parse it.

i modfied my json like this :

{
“cameras”: [
{
“camera_name”: “cam_1”,
“intrinsic_param”: “[[1.92e+03 0.00e+00 9.60e+02]\n [0.00e+00 1.08e+03 5.40e+02]\n [0.00e+00 0.00e+00 1.00e+00]]”,
“transf_matrix”: “[[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]]”
} ]
}[/QUOTE]

and i try to do this :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;




public class Rig : MonoBehaviour
{    public TextAsset jsonFile;

    [System.Serializable]
public class CameraParam
{

 
    public string camera_name;
    public string intrinsic_param;
 
    public List <List <float>> transf_matrix;


}

[System.Serializable]
public class CamerasParam

{
  
    public CameraParam[]
}
    // Start is called before the first frame update
    void Start()
    {
        CamerasParam camerasInJson = JsonUtility.FromJson<CamerasParam>(jsonFile.text); // read the json

        foreach (CameraParam cam in camerasInJson.cameras)
        {

          
            Debug.Log(cam.transf_matrix);



        }
    }


    void Update()
    {
      
    }
}

So, when i try to debug the transf_matrix, its return null.[/QUOTE]

First I’d suggest you use a site like https://json2csharp.com/
Paste your json string in there and it will give you back what the class structure should be. If it isn’t what you expect, you’ll need to format your json string differently. Note that this site uses properties because it is designed to work with Json.net, but if you want to use JsonUtility, just switch them from properties to fields.

Next, if I remember, JsonUtility doesn’t support top level collections. I don’t use JsonUtility myself, as Json.net is far superior in what it is able to handle.

Otherwise, I can quickly tell you, even without using the site that what you expect to happen is not going to happen. within " " is just going to be part of the string and will not create a list of list of floats.

We’d need to see the code you’re using to load the json, but if you’re using JsonUtility, it has a some trouble with arrays and doesn’t do dictionaries at all. If that’s what you’re using, grab the Newtonsoft JSON package via the package manager and use that.

Ok, first of all if you’re not sure if your json is valid or not, head over to a site like jsonlint.com, paste your json and press validate. You get several things for free when you do this. First of all you know if your json is valid and if it can be parsed by a common parser or not. Second you get nice syntax highlighting which makes it easier to read the json and identify the atomic elements your json text is composed of. Finally it does beautify your json by apply proper indention which also helps to see the actual structure of your json.

Your problem is not parsing the json but that your camera object actually only contains 3 string values, specifically “camera_name”, “intrinsic_param” and “transf_matrix”. Those are just string values, so just text from the json’s perspective. The text inside those values do not represent json and is not parsed as json since it’s just text. Since those strings to not represent json you have to parse those strings manually.

The two values “intrinsic_param” and “transf_matrix” just contain this text:

[[1.92e+03 0.00e+00 9.60e+02]
 [0.00e+00 1.08e+03 5.40e+02]
 [0.00e+00 0.00e+00 1.00e+00]]

and

[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]

As I said those text values do not represent json. It seems to be a bit similar to json but the values are whitespace seperated and the matrix values follow an unusual format by ending the values with a dot. Json does seperate values with a comma which is not the case here. Even if there were commas, it’s still just “text” inside your outer json. So if there were commas and the text in those values are valid json, it would need to be parsed seperately.

If you have full control over the json, I would suggest you turn everything into json so it can be parsed properly. Keep in mind that Unity’s JsonUtility does not support jagged or multidimensional arrays. So you would need to use a different parser like Newtonsoft’s Json.NET parser.

This would be everything as pure json:

{
   "cameras": [{
       "camera_name": "cam_1",
       "intrinsic_param": [
           [1.92e+03, 0.00e+00, 9.60e+02],
           [0.00e+00, 1.08e+03, 5.40e+02],
           [0.00e+00, 0.00e+00, 1.00e+00]
       ],
       "transf_matrix": [
           [1, 0, 0, 0],
           [0, 1, 0, 0],
           [0, 0, 1, 0],
           [0, 0, 0, 1]
       ]
   }]
}

This was formatted by jsonlint ^^.

Instead of Json.NET you could also use my SimpleJSON framework and use it with the Unity extention file. This is not an object mapper but it provides an easy direct access to the data stored as json. The Unity extension file adds some implicit conversion operators to support Vectors and also Matrix4x4. Though, currently it does not support a nested matrix format like I just showed but only a single array. Though this could be added. Regardless of the implicit conversion into complex types, you can always directly read the values since the parser just stores everything in Dictionaries / Lists internally.

Thank u all for your answers, it help me a lot.

I was trying to parse a multidimensional array while it was written as a string “” and hadn’t paid attention. I corrected my json, and here is the new version, I also validated that on “jsonlint”, I thank Bunny83 for having made me discover this.

The second problem is from what I understand, it is impossible for me to parse that through JsonUtility, so I have to go through JSON .Net for example?

Thank u very much

Unity’s JSON utility isn’t fully-featured. It’s more like a “tiny” or “lite” JSON, or even “micro” JSON. It simply cannot do a ton of expected features. It is intended for a very narrow fixed data structure use case and fails on Dictionaries, Hashes, properties, and who knows what else.

If you stay within its bounds, you’re golden. Lists of Lists is probably NOT within its bounds.

I highly suggest staying away from Unity’s JSON “tiny lite” package. It’s really not very capable at all and will silently fail on very common data structures, such as Dictionaries and Hashes.

Instead grab Newtonsoft JSON .NET off the asset store for free, as it is way better.

https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347

PS: for folks howling about how it will “add too much size” to your game, JSON .NET is like 307k in size, and it has the important advantage that it actually works the way you expect a JSON serializer to work in the year 2021.

1 Like

Well, from what I heard, specifically for two dimensional arrays / jagged arrays with one nesting level, Unity’s JsonUtility can, sort of parse them when one level is a List and the other an array. Other mixings are not possible ^^. I have never tried this but I read somewhere that this does work

[System.Serializable]
public class CameraDefinition
{
    public string camera_name;
    public List<float[]> intrinsic_param;
    public List<float[]> projection_matrix;
}

[System.Serializable]
public class CameraList
{
    public List<CameraDefinition> cameras;
}

// [ ... ]
CameraList data = JsonUtility.FromJson<CameraList>(yourJsonText);

This should work. Though as Kurt said, the JsonUtility may not be the right tool for this. It’s mainly targetted at extending the serialization system of Unity and not to parse arbitrary json.

ps: just to be clear here. Those variants won’t work:

public List<List<float>> projection_matrix;

// or
public float[][] projection_matrix;

// or
public float[,] projection_matrix;

Those are all not supported by Unity’s serialisation system and this also applies to the JsonUtility.

Yeah, i see.

I tried to do it this way but it doesn’t work. I will try with json.net.

If anyone has an example for Json.NET I’m interested.

It’s basically the most-popular JSON package out there… there’s TONs of example code. Just look in the API reference on line, I’m sure there’s lots of examples.

Thank u again. I saw a few examples of Json.net and i write my code like this :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;



public class Rig : MonoBehaviour
{    public TextAsset jsonFile;

    [System.Serializable]
public class CameraParam
{

  
    public string camera_name;
    public List<List<double>> intrinsic_param;
    public List<List<double>> projection_matrix;
  
   

}

[System.Serializable]
public class CamerasParam

{
   
    public CameraParam[] cameras;
}
    // Start is called before the first frame update
    void Start()
    {
        //CamerasParam camerasInJson = JsonUtility.FromJson<CamerasParam>(jsonFile.text); // read the json
        var camerasInJson = Newtonsoft.Json.JsonConvert.DeserializeObject<CamerasParam>(jsonFile.text);


        foreach (CameraParam cam in camerasInJson.cameras)
        {
     
   
            Debug.Log(cam.projection_matrix);
          



        }
    }


    void Update()
    {
       
    }
}

I want to print the result of my matrix in the console by a debug but i obtain this :

knowing that for the debug of the camera_name, it shows me the different names of cameras ("cam_1, cam_2 …)

Solved ! Thank u all.

1 Like

Hi there, I was wondering if you still had the code for the solution, I have a similar problem and am looking for a solution. Thank you in advance.

What similar problem? You necro posted on a question that is almost 2 years old and was about parsing text of intrinsic camera parameters which were not valid json. So what exact problem you have is similar to this?

Please ask your own question in your own thread and include the relevant details of your specific problem