[SalesForce] Parsing JSON with nesting and Arrays

I'm kinda of new to APEX code and working with JSON and I'm trying to figure out how to parse out nested JSON with Array's. This is a basic pattern of the JSON we have coming into our custom field Order_Content__c via Zapier:

{
"post_title":"e853f34a789f",
"post_name":"e853f34a789f",
"cart": {
    "14": 
        [
            {
                "SKU":"SUPER",
                "name":"Superness",
                "url":"http://localhost:8888/store/products/superness/",
                "price":"0.00",
                "quantity":1,
                "download":{
                    "url":"http://localhost:8888/wp-content/uploads/2014/05/Superness.pdf",
                    "downloaded":0
                }
            }
        ],
    "48":
        [
            {
                "SKU":"TestSKU2",
                "name":"Test2Title",
                "url":"http://localhost:8888/store/products/test2title/",
                "price":"0.00",
                "quantity":1,
                "download":{
                    "url":"http://localhost:8888/wp-content/uploads/2014/05/Test2Title.pdf",
                    "downloaded":0
                }
            }
        ]
    },
"shipping_info": {
    "email":"testemail@gmail.com",
    "name": "TestName",
    "address1":"",
    "address2":"",
    "city":"",
    "state":"",
    "zip":"",
    "country":"US",
    "phone":""
},

"post_status":"order_paid",
"post_type":"mp_order"
}

We then have the following trigger set up when our custom object is updated:

trigger Order_JSON_Dererialize on Order__c (before insert,before update) {

  if(Trigger.new.size() == 1) {

    for (Order__c o: Trigger.new) {
        JSONParser parser = JSON.createParser(o.Order_Content__c);

        while (parser.nextToken() != null) {

            if ((parser.getCurrentToken() == JSONToken.FIELD_NAME)){
                String fieldName = parser.getText();
                parser.nextToken();
                if( fieldName == 'post_title' ) { 
                    o.Order_Number__c = parser.getText();
                } else if( fieldName == 'post_status' ) {
                    o.Order_Status__c = parser.getText();                    
                } else if( fieldName == 'email' ) {
                    //parser.nextToken();
                    o.Shipping_Info_email__c = parser.getText();     
                } else if( fieldName == 'name' ) {
                    o.Name_of_Purchaser__c = parser.getText();    
                } else if( fieldName == 'cart' ) {

                parser.nextToken();
                parser.nextToken();
                    o.Cart_Content__c = parser.getText();
                } else {
                }
            }
        }
    }
  }
}

I am able to get some of the fields I need (post_title, email) and fieldName = 'name' returns the Shipping Info name so that ends up working out but what I really need now is a way to parse out the "cart" arrays. The 14 and 48 correspond to the product ID's. We aren't necessarily set on fields that the product info will be going into but I think at the least, a list of SKU's or name would be nice just to make things easily readable.

Also, the contents of fieldName == 'cart' returns the start of the array (I did this as a test to see how the parser crawled the data).

Any help or insight is greatly appreciated.

Best Answer

Wouldn't it be easier for you to write wrapper classes for your JSON structure and deserialise directly?

Something like this:

public class SuperClass
{
    public String someField1;
    public String someField2;
    public List <NestedClass> arrayOfRecords;
}

public class NestedClass
{
    public String someField3;
}

String testJson = '{"someField1" : "testValue1", "someField2" : "testValue2", "arrayOfRecords" : [ { "someField3" : "testValue3" }, { "someField3" : "testValue4"}]}';

SuperClass sc = (SuperClass)JSON.deserialize(testJson, SuperClass.class);

Then you will be able to access any element from your JSON by using APEX elements.

I think it's a lot easier this way.

EDIT:

If you have dynamic keys in your structure then the above won't work. However, there is still another way of parsing that and it's easier than your approach. Please check the answer to this question.

Related Topic