1

I have a JSON which looks like this,

{
 "users": [
 {
 "displayName": "Sharad Dutta",
 "givenName": "",
 "surname": "",
 "extension_user_type": "user",
 "identities": [
 {
 "signInType": "emailAddress",
 "issuerAssignedId": "[email protected]"
 }
 ],
 "extension_timezone": "VET",
 "extension_locale": "en-GB",
 "extension_tenant": "EG12345"
 }, 
 {
 "displayName": "Sharad Dutta",
 "givenName": "",
 "surname": "",
 "extension_user_type": "user",
 "identities": [
 {
 "signInType": "emailAddress",
 "issuerAssignedId": "[email protected]"
 }
 ],
 "extension_timezone": "VET",
 "extension_locale": "en-GB",
 "extension_tenant": "EG12345"
 }
 ]
}

I am writing a Java code where I am parsing this Multidimensional JSON to FLAT JSON. If you look closely, the JSON is wrapped in a "users" wrapper and then has couple of users as objects. For each user, there is a field called "identifiers" which is again a wrapper.

I want to flat this JSON, I have written a code but it is leaving a JSON blob for identifiers, for non nested it is working fine

JSONObject output;
 try {
 output = new JSONObject(userJsonAsString);
 JSONArray docs = output.getJSONArray("users");
 System.out.println(docs);

This is giving me below output, however i still have to flat inner wrapper "identifiers"

[
 {
 "extension_timezone": "VET",
 "extension_tenant": "EG12345",
 "extension_locale": "en-GB",
 "identities": [
 {
 "signInType": "emailAddress",
 "issuerAssignedId": "[email protected]"
 }
 ],
 "displayName": "Sharad Dutta",
 "surname": "",
 "givenName": "",
 "extension_user_type": "user"
 },
 {
 "extension_timezone": "VET",
 "extension_tenant": "EG12345",
 "extension_locale": "en-GB",
 "identities": [
 {
 "signInType": "userName",
 "issuerAssignedId": "pdhongade007"
 }
 ],
 "displayName": "Wayne Rooney",
 "surname": "Rooney",
 "givenName": "Wayne",
 "extension_user_type": "user"
 }
]

This is what I need,

{
 "extension_timezone": "VET",
 "extension_tenant": "EG12345",
 "extension_locale": "en-GB",
 "signInType": "emailAddress",
 "issuerAssignedId": "[email protected]",
 "displayName": "Sharad Dutta",
 "surname": "",
 "givenName": "",
 "extension_user_type": "user"
 }

I have to then parse this to CSV, which I know how, I just need to flat this further. Any help will be appreciated. I tried looking around, but a lot of them were using external dependencies.

//UPDATE

{
 "extension_timezone": "VET",
 "extension_tenant": "EG12345",
 "extension_locale": "en-GB",
 "signInType": "userName",
 "displayName": "Wayne Rooney",
 "surname": "Rooney",
 "givenName": "Wayne",
 "issuerAssignedId": "pdhongade007",
 "extension_user_type": "user"
}

When I tried @Jakub solution, I am getting the flat JSON, however it is not iterating for all the users. Just one!(I am guessing the last user only)

asked Sep 18, 2020 at 11:09

2 Answers 2

1

Please try the below approach, this will give you a comma separated format for both user and identifier (flat file per se),

 public static void main(String[] args) throws JSONException, ParseException {
 
 String userJsonFile = "path to your JSON";
 final StringBuilder sBuild = new StringBuilder();
 final StringBuilder sBuild2 = new StringBuilder();
 
 try {
 String userJsonAsString = convert your JSON to string and store in var;
 } catch (Exception e1) {
 e1.printStackTrace();
 }
 JSONParser jsonParser = new JSONParser();
 JSONObject output = (JSONObject) jsonParser.parse(userJsonAsString);
 try {
 
 JSONArray docs = (JSONArray) output.get("users");
 Iterator<Object> iterator = docs.iterator();
 
 
 while (iterator.hasNext()) {
 JSONObject userEleObj = (JSONObject)iterator.next();
 JSONArray nestedIdArray = (JSONArray) userEleObj.get("identities");
 Iterator<Object> nestIter = nestedIdArray.iterator();
 
 while (nestIter.hasNext()) {
 JSONObject identityEleObj = (JSONObject)nestIter.next(); 
 identityEleObj.keySet().stream().forEach(key -> sBuild2.append(identityEleObj.get(key) + ","));
 userEleObj.keySet().stream().forEach(key -> {
 if (StringUtils.equals((CharSequence) key, "identities")) {
 sBuild.append(sBuild2.toString());
 sBuild2.replace(0, sBuild2.length(), "");
 } else {
 sBuild.append(userEleObj.get(key) + ","); 
 }
 
 });
 
 }
 sBuild.replace(sBuild.lastIndexOf(","), sBuild.length(), "\n"); 
 }
 
 System.out.println(sBuild);
 
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
answered Sep 21, 2020 at 10:34
Sign up to request clarification or add additional context in comments.

1 Comment

I tried you approach it worked! perfectly. thanks I am marking as answer
1

You can traverse the json and just store the "leafs" in map. Note: array of primitives will turn into the last value in the array with this approach, but that's what you described :)

Something like this:

void flatJson() throws JSONException {
 JSONObject object = new JSONObject(userJsonAsString); // this is your input
 Map<String, Object> flatKeyValue = new HashMap<>();
 readValues(object, flatKeyValue);
 System.out.println(new JSONObject(flatKeyValue)); // this is flat
}
void readValues(JSONObject object, Map<String, Object> json) throws JSONException {
 for (Iterator it = object.keys(); it.hasNext(); ) {
 String key = (String) it.next();
 Object next = object.get(key);
 readValue(json, key, next);
 }
}
void readValue(Map<String, Object> json, String key, Object next) throws JSONException {
 if (next instanceof JSONArray) {
 JSONArray array = (JSONArray) next;
 for (int i = 0; i < array.length(); ++i) {
 readValue(json, key, array.opt(i));
 }
 } else if (next instanceof JSONObject) {
 readValues((JSONObject) next, json);
 } else {
 json.put(key, next);
 }
}
answered Sep 18, 2020 at 11:49

11 Comments

Do you have a link?
Not sure what link you are after ?
I was trying to read you code, I am not sure about calling structure, and where I am feeding my JSON string in the code. I am trying to write a code which will follow a main() method type of structure. I am not sure how will I embed your code in mine.
I added comments to make it easier to follow, you can copy-paste the code and put content of flatJson into main method to run it.
I tried your solution, it is giving me a flat JSON but its is not giving output for both users, just one user ( the last user it got) i think some problem with iterator.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.