0

I have received a Json file which I have to deal with. I have no idea over the structure. My goal is to deserialize the Json and write a function which allows me to iterate through all the given objects and print certain values. File looks like this:

    {
    "stream": {
        "time": [ 0, 1, 2 ],
        "objects": {
            "o1": {
                "rot_1": [ 3.7, 3.9, 2.1 ],
                "rot_2": [ 1.5, 1.7, 0 ],
                "rot_3": [ 3, 4, 5 ]
            },
            "o2": {
                "rot_1": [ 5, 6, 7 ],
                "rot_2": [ 8, 9, 10 ],
                "rot_3": [ 11, 12, 13 ]
            }

        }
    }

  

Now I am using Newtonsoft.Json to deserializing as a class like this:

public class O1
{
    public List<double> rot_1 { get; set; }
    public List<double> rot_2 { get; set; }
    public List<double> rot_3 { get; set; }
}

public class O2
{
    public List<double> rot_1 { get; set; }
    public List<double> rot_2 { get; set; }
    public List<double> rot_3 { get; set; }
}

public class Objects
{
    public O1 o1 { get; set; }
    public O2 o2 { get; set; }
}

public class Stream
{
    public List<double> time { get; set; }
    public Objects objects { get; set; }
}

public class Root
{
    public Stream stream { get; set; }
}



class Program
{
    static void Main(string[] args)
    {
       
        var x = JsonConvert.DeserializeObject<Root>(File.ReadAllText("E:\\TestJson.json"));

        foreach (PropertyInfo info in x.stream.objects.GetType().GetProperties())
        {
            // print:
            // o1 -> rot_1 -> 3.7, 3.9, 2.1 
            // o2 -> rot_1 -> 5, 6, 7 
            // ....          


        }


    }

}

I have been trying to make PropertyInfo work, but I can't find a way to go "deeper". I have a feeling this might be a pretty trivial question... Sorry I am a noob ...

2
  • I am not sure what are you trying to achieve. If you just want to deserialize (ie create instance of object from json string), you dont need to do anything except calling “deserialize” method (also, I think it is better practice to use System.Text.Json instead of Newtonsoft). Or is it your goal to iterate through properties in some generic manner (which implies you don’t actually know the structure of given json)? Commented Apr 28, 2021 at 12:13
  • You want to enumerate thought those because they are not properties but dictionary : [JsonProperty("objects")] public Dictionary<string, Dictionary<string, List<double>>> Objects { get; set; } instead of public Objects objects { get; set; } Commented Apr 28, 2021 at 12:14

2 Answers 2

1

Change your object to :

public partial class Root
{
    [JsonProperty("stream")]
    public Stream Stream { get; set; }
}

public partial class Stream
{
    [JsonProperty("time")]
    public List<long> Time { get; set; }

    [JsonProperty("objects")]
    public Dictionary<string, Dictionary<string, List<double>>> Objects { get; set; }
}

Iterating througth it like :

foreach(var obj in  result.Stream.Objects){
    Console.WriteLine($"object name : [{obj.Key}]");
    foreach(var element in obj.Value){
        Console.WriteLine($"  -> element name : [{element.Key}]");
        foreach(var val in element.Value){              
            Console.WriteLine($"    -> value: [{val}]");
        }
    }
    Console.WriteLine();
}

Result :

object name : [o1]
  -> element name : [rot_1]
    -> value: [3.7]
    -> value: [3.9]
    -> value: [2.1]
  -> element name : [rot_2]
    -> value: [1.5]
    -> value: [1.7]
    -> value: [0]
  -> element name : [rot_3]
    -> value: [3]
    -> value: [4]
    -> value: [5]

object name : [o2]
  -> element name : [rot_1]
    -> value: [5]
    -> value: [6]
    -> value: [7]
  -> element name : [rot_2]
    -> value: [8]
    -> value: [9]
    -> value: [10]
  -> element name : [rot_3]
    -> value: [11]
    -> value: [12]
    -> value: [13]

Live demo: https://dotnetfiddle.net/5QIeHJ

Sign up to request clarification or add additional context in comments.

2 Comments

This is exactly what i was looking for. Thank you!
I gonna give you my secret. When Property name look like value i always assume it's a dictionary. Then I slap the Json in this app.quicktype.io. and rename the name by 1,2,3 etc. Then the tool create the class.
0

There are many ways to skin this cat.

There is the dictionary or dictionaries way that others suggested and there is the crude way that will work OK if it's always two os and 3 rot_s :

static void WriteLine(string name, List<double> l) => Console.WriteLine($"{name} -> {string.Join(",", l)}");

// Option 1:
WriteLine("o1 -> rot_1", x.stream.objects.o1.rot_1);
WriteLine("o1 -> rot_2", x.stream.objects.o1.rot_2);
...

It prints what it needed:

o1 -> rot_1 -> 3.7,3.9,2.1
o1 -> rot_2 -> 1.5,1.7,0
...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.