3

I have a json string as name value pair , but when i use json.serialised , it reorders as value and name for every attributes ,Ideally system will find the attribute based on name , I am pushing it as name first and then the value, `

{"payload":[{"value":"4.6","name":"YearlylCostPercentage"},{"value":"120000","name":"TotalRepayment"},{"value":"100000","name":"PropertyMarketValue"},{"value":"ABN Standard+","name":"productname"},{"value":"Monthly","name":"PaymentFrequency"},{"value":"60","name":"NumberOfTerms"},{"value":"Notary","name":"NotaryName"},{"value":"raju.sen@yahoo.com","name":"NotaryEmail"},{"value":"0649991729","name":"NotaryContactNumber"},{"value":"2563 CM The Hague","name":"NotaryAdressLine2"},{"value":"Valkenboslaan 72-F","name":"NotaryAdressLine1"},{"value":"4.5","name":"nominalInterestRate"},{"value":"600","name":"MonthlyPayment"},{"value":"300","name":"MonthlyInterestAmount"},{"value":"12-1-2019","name":"loanUtilizationDate"},{"value":"Loan","name":"loanPurpose"},{"value":"12-2-2019","name":"loanMaturityDate"},{"value":"5","name":"LoanDuration"},{"value":"100000","name":"loanAmount"},{"value":"Amsterdam","name":"KadasterLocation"},{"value":"1.0","name":"InterestFixationProvision"},{"value":"900","name":"HandlingCost"},{"value":"2.0","name":"FixedInterestyear"},{"value":"12-2-2019","name":"firstPaymentDate"},{"value":"700","name":"FirstMonthlyPayment"},{"value":"4.7","name":"effectiveInterestRate"},{"value":"Dev","name":"DepartmentName"},{"value":"Amsterdam","name":"city"},{"value":"1.4","name":"BorrowedRatio"},{"value":"Raju Sen","name":"AdvisorName"},{"value":"0649991729","name":"AdvisorContact"},{"value":"1000","name":"AdviseCost"},{"value":[{"value":"Geen titulatuur gewenst","name":"CustomerSalutation"},{"value":"Eqaavq","name":"CustomerName"},{"value":"1221 NH MDFMGDAKSV","name":"AddressLine2"},{"value":"Wdr Veuniztapbmr 345","name":"AddressLine1"},{"value":"Mevrouw","name":"CustomerSalutation"},{"value":"Eqaavq-col Fpcysfptp","name":"CustomerName"},{"value":"1221 NH MDFMGDAKSV","name":"AddressLine2"},{"value":"Wdr Veuniztapbmr 345","name":"AddressLine1"}],"name":"CustomerDetails"}]}`

Code Sample:

 string jsonBody='{"payload":[{"YearlylCostPercentage":"4.6","TotalRepayment":"120000","PropertyMarketValue":"100000","productname":"ABN Standard+","PaymentFrequency":"Monthly","NumberOfTerms":"60","NotaryName":"Notary","NotaryEmail":"raju.sen@yahoo.com","NotaryContactNumber":"0649991729","NotaryAdressLine2":"2563 CM The Hague","NotaryAdressLine1":"Valkenboslaan 72-F","nominalInterestRate":"4.5","MonthlyPayment":"600","MonthlyInterestAmount":"300","loanUtilizationDate":"12-1-2019","loanPurpose":"Loan","loanMaturityDate":"12-2-2019","LoanDuration":"5","loanAmount":"100000","KadasterLocation":"Amsterdam","InterestFixationProvision":"1.0","HandlingCost":"900","FixedInterestyear":"2.0","firstPaymentDate":"12-2-2019","FirstMonthlyPayment":"700","effectiveInterestRate":"4.7","DepartmentName":"Dev","CustomerDetails":[{"CustomerSalutation":"Geen titulatuur gewenst","CustomerName":"Eqaavq","AddressLine2":"1221 NH MDFMGDAKSV","AddressLine1":"Wdr Veuniztapbmr 345"},{  "CustomerSalutation":"Mevrouw","CustomerName":"Eqaavq-col Fpcysfptp","AddressLine2":"1221 NH MDFMGDAKSV","AddressLine1":"Wdr Veuniztapbmr 345"}],"city":"Amsterdam","BorrowedRatio":"1.4","AdvisorName":"Raju Sen","AdvisorContact":"0649991729","AdviseCost":"1000"}]}';
Map<String, Object> jsonParseSource = (Map<String, Object>)JSON.deserializeUntyped(jsonBody);
system.debug('Sai tets '+jsonParseSource);
List<Map<String, String>> payload = new List<Map<String, String>>();
List<Object> payLoadList=(List<Object>) jsonParseSource.get('payload');
Object PayloadObj;
if(payLoadList.size()>0)
{
    PayloadObj=payLoadList[0];
}
String customerDetailString='';
Map<String, Object> payloadBody = (Map<String, Object>)PayloadObj;
system.debug('Sai tets '+payloadBody);
for(String key: payloadBody.keyset()) {
    system.debug('Key '+key+ ' Value '+payloadBody.get(key));
    if(key == 'CustomerDetails')
    {
        List<Map<String,String>> tempMap= new List<Map<String,String>>();
        List<Object> tempList=(List<Object>)payloadBody.get(key);
        for(Object obj : tempList)
        {
            Map<String, Object> tempObj = (Map<String, Object>)obj;
            for(String tempKey: tempObj.keyset())
            {
                tempMap.add(new Map<String, String> { 'name' => tempKey, 'value' => (String)tempObj.get(tempKey) });
                system.debug('List Key '+tempKey+ ' List Value '+tempObj.get(tempKey));
            }
        }
        system.debug('tempMap'+tempMap);
        customerDetailString=JSON.serialize(new Map<String, List<Map<String, String>>> {
            key => tempMap
                });
                system.debug('customerDetailString'+customerDetailString);
    }
    else
    {
        payload.add(new Map<String, String> { 'name' => key, 'value' => (String)payloadBody.get(key) });
    }    
}
String jsonResult = JSON.serialize(new Map<String, List<Map<String, String>>> {
    'payload' => payload
        }); 
String custpomerObjTemp=customerDetailString.substringAfter(':');
system.debug(custpomerObjTemp);
custpomerObjTemp=custpomerObjTemp.Left(custpomerObjTemp.Length() - 1);
system.debug('Reult '+ custpomerObjTemp);
String finalResult=jsonResult.Left(jsonResult.Length() - 2);
finalResult=finalResult+',{"value":'+custpomerObjTemp+',"name":"CustomerDetails"}]}';
system.debug(finalResult);
6

The attributes in JSON are not ordered, so serialise/deserialise does not need to preserve that order.

The JSON syntax does not impose any restrictions on the strings used as names, does not require that name strings be unique, and does not assign any significance to the ordering of name/value pairs.

See the standard here: http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf

Note that lists within JSON are ordered. So, if you care about ordering, have a list of objects.

  • Out of curiosity, XML does? – Pranay Jaiswal Nov 16 '18 at 11:09
  • 1
    @PranayJaiswal Ordering may or may not be significant in XML: that can be specified in the XML Schema definition (or informally). – Keith C Nov 16 '18 at 11:16
3

Bizarrely the Apex serialize outputs the names in reverse alphabetic order for some (implementation dependent presumably) reason. Not very human-friendly when debugging or persisting JSON. Wonder why the code review of that feature didn't suggest alphabetic order...

As Aidan says, as the ordering is not part of the spec you cannot rely on it. That means in e.g. unit tests don't compare JSON text but instead the parsed JSON (which also avoids white spacing variations which again are allowed in the spec).

My goto reference on JSON is this single page https://www.json.org/.

  • would json generator be handy , for this situation to recreate the whole json again from the start – Raju Sen Nov 16 '18 at 11:50
  • @RajuSen I use the methods JSON.deserialize, JSON.deserializeUntyped, JSON.serialize, and JSON.serializePretty for all my Apex JSON work. – Keith C Nov 16 '18 at 12:21
  • I'll have to admit, I rely on the reverse alpha order "feature" to make it easy to compare expected JSON to actual JSON in testmethods through simple string compare of two serialized objects. I guess I've been playing with fire. – cropredy May 15 at 17:12
  • @cropredy Bet you’re not the only one so unlikely to ever change. – Keith C May 15 at 18:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.