0

I have a JSON string that I'm working with and want to deserialize and reference in Apex. The Problem is that the structure of the JSON is somewhat flexible. For Example, it could look like:

       {
            "level 1" : {
                "level 2" :{
                    "String 1" : {
                        "Attribute a" : "xyz",
                        "Attribute b : xyz"
                    }
                }
            }
        }

Or it could look like:

{
    "level 1" : {
        "level 2" :{
            "Random String" : {
                "Attribute a" : "xyz",
                "Attribute b : xyz"
            },
            "Different Random String" : {
                "Attribute a" : "xyz",
                "Attribute b : xyz"
            }
        }
    }
}

The issue is that I can't deserialize this to a class becuase I don't know what the name of the object under Level 2 would be. And I also can't seem to use JSON.deserializeUntyped because once I get an Object version of Level 2, there's no way (as far as I can tell) to get it's attributes.

It seems that I can keep using Object Maps down several levels but I was wondering if anyone has a better solution to this problem?

2 Answers 2

1

Ok, I figured out the answer to my own question.

I can create a class like this:

public class level1{
    public Level2 level2 {get; set;}

    public class level2 {
        public Map<String, List<Level3>> optionConfigurations {get; set;}
    }
    public class level3{
        public String attribute1 {get; set;}
        public String attribute2 {get; set;}
    }
}
0

This is an inelegant solution but it may help your understanding of how to get the data from the attributes from the nested maps.

And I also can't seem to use JSON.deserializeUntyped because once I get an Object version of Level 2, there's no way (as far as I can tell) to get it's attributes.

The documentation about the deserializeUntyped() method uses array syntax to get items from list indexes, which may come in handy if your payload includes lists in addition to maps/JSON objects. The example code below uses your original JSON, which is all maps.

string jsonInput = '{"level 1":{"level 2":{"Random String":{"Attribute a":"xyz","Attribute b":"xyz"},"Different Random String":{"Attribute a":"xyz","Attribute b":"xyz"}}}}';

Map<String, Object> payload = (Map<String, Object>)JSON.deserializeUntyped(jsonInput);

for (String key1: payload.keyset()) {
    Map<String, Object> level1Map = (Map<String, Object>)payload.get(key1);
    system.debug('Key1: ' + key1 + ': ' + payload.get(key1));

    for (String key2: level1Map.keyset()) {
        system.debug('Key2: ' + key2 + ': ' + level1Map.get(key2));
        Map<String, Object> level2Map = (Map<String, Object>)level1Map.get(key2);

        for (String key3: level2Map.keyset()) {
            system.debug('Key3: ' + key3 + ': ' + level2Map.get(key3));  

            Map<String, Object> level3Map = (Map<String, Object>)level2Map.get(key3);

            for (String key4: level3Map.keyset()) {
                system.debug('Key4: ' + key4 + ': ' + level3Map.get(key4));        
            }
        }
    }
}

As can be seen in the image, each for loop progresses one level deeper in the hierarchy. I'll leave it up to the reader to implement a recursive loop to the full depth of the object.

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .