Multidimentional JSON to CSV , non-nested CSV convertion working in JAVA - java

I have a JSON file which I need to flat and create a CSV from it. I was able to convert to CSV (I have a "users" wrapper) but inside "users" there is another wrapper named "identifiers", I want to iterate them as well and create a field for them.
I have a JSON file which looks like this :
{
"users": [
{
"displayName": "Sharad Dutta",
"givenName": "",
"surname": "",
"extension_user_type": "user",
"identities": [
{
"signInType": "emailAddress",
"issuerAssignedId": "kkr007#gmail.com"
}
],
"extension_timezone": "VET",
"extension_locale": "en-GB",
"extension_tenant": "EG12345"
},
{
"displayName": "Wayne Rooney",
"givenName": "Wayne",
"surname": "Rooney",
"extension_user_type": "user",
"identities": [
{
"signInType": "userName",
"issuerAssignedId": "kkr007"
}
],
"extension_timezone": "VET",
"extension_locale": "en-GB",
"extension_tenant": "EG12345"
}
]
}
I am trying to convert the JSON to CSV and this is what I was able to do :
Below is the code : As you can see, my JSON is wrapped inside a "users" type wrapper and in the JSON i have one more wrapper "identities", with the code that I did, I am able to iterate but the "identites" is coming out as JSON blob, I want something like this in place of identites
issuerType issuerAssignedId
bla bla bla bla bla bla
and not a JSON nested blol for identites.
public static void main(String[] args) throws JSONException {
String userJsonFile = "C:\\Users\\Administrator\\Desktop\\jsonRes\\json_format_user_data_input_file.json";
try {
userJsonAsString = readFileAsAString(userJsonFile);
} catch (Exception e1) {
e1.printStackTrace();
}
JSONObject output;
try {
output = new JSONObject(userJsonAsString);
JSONArray docs = output.getJSONArray("users");
File file = new File("C:\\Users\\Administrator\\Desktop\\jsonRes\\EmpDetails.csv");
String csv = CDL.toString(docs);
FileUtils.writeStringToFile(file, csv);
System.out.println("Data has been Sucessfully Writeen to " + file);
System.out.println(csv);
} catch (Exception e) {
e.printStackTrace();
}
}
private static String readFileAsAString(String inputJsonFile) throws Exception {
return new String(Files.readAllBytes(Paths.get(inputJsonFile)));
}

Welcome to SO!
As you rightly said, "identities" is a nested JSON Array inside each element of the "users" array. So, when you flatten into a more-or-less relational format (here CSV), you would typically need to repeat the rest of the info for each element of the "identitites" array.
Now, whichever JSON parsing library you are using (JSONObject in you snippet, I am assuming comes from org.json jar?), you would need to iterate through the JSONArray docs and for each element call the getJSONArray("identities").
Since it is a nested array, you would need two loops to handle this scenario.
outer loop for the "users" array and a nested loop for the "identities" on each element of the "users" array.
Please use the below snippet as a reference only. Have written according to your code snippet. Please use standard variable naming and practices. This is just to show you the logic
String userJsonAsString="";
StringBuilder sBuild = new StringBuilder();
StringBuilder sBuild2 = new StringBuilder();
try {
userJsonAsString = readFileAsAString(userJsonFile);
} catch (Exception e1) {
e1.printStackTrace();
}
JSONObject output;
try {
output = new JSONObject(userJsonAsString);
JSONArray docs = output.getJSONArray("users");
Iterator<Object> iter = docs.iterator();
while(iter.hasNext()) {
JSONObject userEleObj = (JSONObject)iter.next();
JSONArray nestedIdArray = userEleObj.getJSONArray("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(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();
}

Related

How can I make an JSON in Java with org.json which does look like this example?

So, I tried something with java which looks like this, but the output does not look nice.
One of the code-examples I tried to make a json file with:
String name = "usericals.json";
JSONObject jsonObj = new JSONObject();
JSONArray scene = new JSONArray();
JSONArray element = new JSONArray();
jsonObj.put("scene", scene);
for (int i = 0; i < 1; i++) {
for (int ii = 0; ii < 1; ii++) {
element.put(write);
}
jsonObj.put("element", element);
}
scene.put(element);
try (PrintWriter writer = new PrintWriter("new.json", "UTF-8")) {
writer.write(jsonObj.toString(4));
} catch (Exception ex) {
System.out.println("exception " + ex);
}
I wanted to make a json file which looks like this but I cannot get it right. I am creating with my code above only arrays. Does anyone have an idea or suggestion?
The JSON File I want:
{
"scene": [
{
"id": 0,
"calendar_event": "urlaub",
"element": [
{
"anything": ""
},
{
"anything": ""
}
]
},
{
"id": 1,
"calendar_event": "urlauburlaub",
"element": [
{
"anything": ""
},
{
"anything": ""
}
]
},
{
"id": 2,
"calendar_event": "urlauburlauburlaub",
"element": [
{
"anything": ""
},
{
"device": "",
"anything": ""
}
]
},
{
"id": 3,
"calendar_event": "urlauburlauburlauburlaub",
"element": [
{
"anything": ""
},
{
"anything": ""
}
]
}
]
}
I suggest using library for that. Jackson or GSON would be a good choice.
Instead of manually creating json field by field you could create POJOs and then use Jackson's ObjectMapper. Example:
public class Car {
private String color;
private String type;
// standard getters setters
}
and then
ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car("yellow", "renault");
objectMapper.writeValue(new File("target/car.json"), car);
Which will give
{"color":"yellow","type":"renault"}
Google has a lot of jackson tutorials!
Use JSONObject recursively. Try something like this (I add some extra indentation so it can be readed easily, but on real projects better use functions instead):
JSONObject json = new JSONObject();
JSONArray scene = new JSONArray();
JSONObject node = new JSONObject();
node.put("id", 0);
node.put("calendar_event", "urlaub");
JSONArray element = new JSONArray();
JSONObject enode = new JSONObject();
enode.put("anything", "");
element.add(enode);
//...
node.put("element", element);
scene.add(node);
json.put("scene", scene);
//...
Note like this you generate manually the JSONs, but there are other libraries that scan objects to generate jsons. Depending on your needs, it could be easer, but remember that making so you are going to overhead everything because you are going to need to hold in memory two copies of the same tree. Also dealing with hierarchical structures maybe a problem using plain java objects.

How to modify the value of a particular field in a JSON file using json-simple, after parcing the JSON file

I need to modify a particular value of a key in my json file, it is a nested JSON file and i have traversed till that key value pair but i'm not able to modify the value and don't know how to write back to the json.
Using json-simple to parse the JSON
This is the JSON file:
{
"entity": {
"id": "ppr20193060018",
"data": {
"relationships": {
"productpresentationtolot": [
{
"id": "",
"relTo": {
"id": "",
"data": {
"attributes": {
"rmsitemid": {
"values": [
{
"source": "internal",
"locale": "en-US",
"value": "2019306"
}
]
}
}
},
"type": "lot"
}
}
]
}
},
"type": "productpresentation"
}
}
Reading it using below code:
JSONParser parser = new JSONParser();
reader = new FileReader("path.json");
JSONArray rmsArray =(JSONArray) rmsitemid.get("values");
for(Object obj2:rmsArray)
{
JSONObject tempObj1=(JSONObject)obj2;
System.out.println(tempObj1.get("value"));
}
I'm able to print what is there in value(Key) i.e., 2019306 but i don't have any idea how can i replace it with some other value and it should change the value in JSON file also.
Any help appreciated!
Here is a complete exmaple how to read and write using the simple-json library:
// read from resource file
JSONObject value;
try (Reader in = new InputStreamReader(getClass().getResourceAsStream("/simple.json"))) {
JSONParser parser = new JSONParser();
value = (JSONObject) parser.parse(in);
}
JSONObject entity = (JSONObject) value.get("entity");
// update id
entity.put("id", "manipulated");
// write to output file
try (Writer out = new FileWriter("output.json")) {
out.write(value.toJSONString());
}
The JSONObjects are basically Maps. So you can just put values inside.
In order to create a JSON string again, use toJSONString().
In my example, I create a new output file. You could also override the original input file, though. But you have to write the file completely.

How to get JSON data that contains JSON Object and array both

*I am already getting this JSON object from responce.body(). I want every data inside this separately in variable. I am using java.
{
"Classes":{
"Primary":{
"Classes":{
"1":{
"section":[
"a",
"b"
]
},
"2":{
"sections":[
"a",
"b"
]
}
}
}
}
}
*I know how to get the JSONObject but i dont know how can i get that array inside "section". even if i get that array with JSONArray then how to convert it to JSONObject? or String.
*Note that inside value of "section" array is dynamic, value inside that array is dynamic and can be multiiple from "a" to "z". Also JSONObject inside "Classes"(inside primary) is also dynamic. there can be dynamic and multiple "1","2"... and it is string, It is not necessary that there will be incremental numbers.
After 30 mins of war, I find out your answer just copy this code and paste where you want to use -
Here it is -
String json = "{
"Classes": {
"Primary": {
"Classes": {
"1": {
"section": [
"a",
"b"
]
},
"2": {
"sections": [
"a",
"b"
]
}
}
}
}
}";
try {
JSONObject jsonObject = new JSONObject(json);
Log.d("jsonObj", jsonObject.toString());
JSONObject classJsonObj = jsonObject.optJSONObject("Classes");
JSONObject primaryJsonObj = classJsonObj.optJSONObject("Primary");
JSONObject internalClassJsonObj = primaryJsonObj.optJSONObject("Classes");
if(internalClassJsonObj != null){
int i = 1;
JSONObject dynmaicInternalJsonObj = null;
while (true){
dynmaicInternalJsonObj = internalClassJsonObj.optJSONObject(i+"");
if(dynmaicInternalJsonObj != null){
JSONArray sectionJsonArr = dynmaicInternalJsonObj.optJSONArray("sections");
Log.d("SectionArr", sectionJsonArr.toString());
// Finally you got your section data here...
if(sectionJsonArr != null){
for(int j=0; j<sectionJsonArr.length(); j++){
System.out.println("Dynamic Sections Data is: - " + sectionJsonArr.opt(j));
}
System.out.println("\n\n");
}
}else{
break;
}
i++;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
You've tagged this as java so I can only assume you want a solution for that language.
To use this data it needs to parsed, this means you are converting the data into a more usable type.
Click this to learn how to parse JSON in java
Assuming you need solution in java, use this to get a object classes for your json structure and then convert your json to java objects using libraries like GSON.
Example:
String json = "{\"city\":\"San Jose\", \"state\": \"CA\", \"country\":\"USA\"}";
Gson gson = new Gson();
Place place = gson.fromJson(json, Place.class);
If you are using ionic (typescript or javascript), you can use the below approach
var json = "{
"Classes": {
"Primary": {
"Classes": {
"1": {
"section": [
"a",
"b"
]
},
"2": {
"sections": [
"a",
"b"
]
}
}
}
}
}";
for(let item in json.Classes.Primary.Classes){
console.log(item.sections);
}
If you want to display the same data in frontend using html, use *ngFor
<div *ngFor="let item in json.Classes.Primary.Classes ">
<h5>{{item.sections}}</h5>
</div>
I hope it helps.

Creating JSON in required format - Java

I am not very experienced in this so need help.I need following things to be done :
1. Want to traverse a folder structure in a content management repository.
2. Want to create JSON Object of the folder in child-node form.
3. Json data will be used to create tree using jQuery
Json format:
var data = [
{
text: "Parent 1",
nodes: [
{
text: "Child 1",
nodes: [
{
text: "Grandchild 1"
},
{
text: "Grandchild 2"
}
]
},
{
text: "Child 2"
}
]
},
{
text: "Parent 2"
},
{
text: "Parent 3"
},
{
text: "Parent 4"
},
{
text: "Parent 5"
}
];
My Java method is like this:
public static void displayIt(File node){
System.out.println(node.getAbsoluteFile());
if(node.isDirectory()){
String[] subNote = node.list();
for(String filename : subNote){
displayIt(new File(node, filename));
}
}
}
I am Struggling to frame strategy to create JSON object and Array to depict this.
Please can you help me.
If you want to read all files or folder from content management repository using recursion than use below function :
public static MyFolder readFiles(File file,List<MyFolder> myfolder,MyFolder childObj)
{
try
{
List<MyFolder> childArray = new ArrayList<MyFolder>();
if(file.isDirectory())
{
File[] file_array = file.listFiles();
if(file_array.length == 0 ){
childObj.text = file.getAbsolutePath();
myfolder.add(childObj);
childObj = new MyFolder();
}else{
childObj.text = file.getAbsolutePath();
childArray = childObj.nodes;
if(childArray == null)
childArray = new ArrayList<MyFolder>();
}
for(File tempFile : file_array)
{
if(tempFile.isDirectory())
{
childObj = readFiles(tempFile,myfolder,childObj);
if(childObj.text != null)
myfolder.add(childObj);
childObj = new MyFolder();
}
else
{
MyFolder obj = new MyFolder();
obj.text = tempFile.getAbsolutePath();
childArray.add(obj);
}
}
childObj.nodes = childArray;
}
else
{
childObj.text = file.getAbsolutePath();
myfolder.add(childObj);
childObj = new MyFolder();
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
return childObj;
}
MyFolder Class :
class MyFolder
{
String text;
List<MyFolder> nodes;
}
You need some JSON utility or API to convert your class into json string. I have used GSON google API to convert my List<MyFolder> to JSON string.
Below is my test Class to test above :
List<MyFolder> myFolder = new ArrayList<MyFolder>();
File file = new File("D:/test");
MyFolder childArray = new MyFolder();
readFiles(file,myFolder,childArray);
Gson json = new Gson();
System.out.println(json.toJson(myFolder));
Output is :
[
{
"text": "D:\\test\\test1\\test12",
"nodes": [
{
"text": "D:\\test\\test1\\test12\\test12.txt"
},
{
"text": "D:\\test\\test1\\test12\\test12_2.txt"
}
]
},
{
"text": "D:\\test\\test2"
},
{
"text": "D:\\test\\test3"
}
]
Last thing remaining is just passed this to client side and process JSON to generate tree stucture.
May this will help you.
There's a way in JAVA to produce a JSON object from different collection types - Flexjson. Here you can find most essential information about Flexjson. In short, the command looks like this:
String jsonString = new flexjson.JSONSerializer().deepSerialize(myCollection);
Jquery perfectly understands the resulting JSON object and you can easily access the contents in JQuery like this:
jsonString["column1"]
So, you can just save data in an Arra/Map/whatewer is suitable for your situation and then translate in to JSON.
Hope it helps, I use this method every time I need a JSON string and works perfectly for me.

Convert JSON string to plain key value pair for logging

I have a JSON string, where consist of structure something like below, basically I have a chain of VO's and each VO will have list of VO's and Map of VO's as well.
sample:
"MessageHeader": {
"type": "new",
"id": 10,
"add_record": "true",
},
"MessageBody": {
"dob_required": false,
"dept_name": "Purchase",
"group": {
"main_group": "main group",
"sub_group": "sub group"
},
"family_info": {
"person1": {
"name": "HisName",
"gender": "male",
"age": "31",
"office_info_present": {
"office_name": "present office",
"office_address": "some address"
"some_other_vo":{
},
},
"office_info_previous": {
"office_name": "old office",
"office_address": "some address"
},
},
"person2": {
"name": "HerName",
"gender": "Female",
"age": "25",
}
},
"active":true
}
I want to print each and every attribute name and its value in key value pair. I don't want to print the VO name, rather just the end attributes (leaf level attributes)
like below string:
type=new id=10 add_record=true dob_required=false dept_name=purchase main_group="main group" sub_group="sub group" name=HisName gender=male age=31 .... name=HerName gender=Female age=25
How this can be done? I would prefer if it can be done using jackson. Otherwise also fine.
The easiest way is probably by using Jackson's Tree Model, traversing it. Something like:
JsonNode root = mapper.readValueAsTree(jsonInput);
Map<String,String> flat = new HashMap<String,String>();
traverse(root, flat);
public void traverse(JsonNode node, Map<String,String> result)
{
Iterator<Map.Entry<String,JsonNode>> it = node.fields();
while (it.hasNext()) {
Map.Entry<String,JsonNode> entry = it.next();
JsonNode n = entry.getValue();
if (n.isObject()) { // if JSON object, traverse recursively
traverse(n);
} else { // if not, just add as String
result.put(entry.getKey(), n.asText());
}
}
}
and you'll get a Map that you can print.
you can use this link for creating POGO class for your response. It will automatically generate class for your response.
Use google GSON library to parse your response.
Yes jackson can be used to parse. but its not straight forward.
There are few implementations similar to JAXB for XML. But I never tested them
Here is the rough code snippet.
JSONParser parser = new JSONParser();
try {
JSONObject jsonObject = (JSONObject) parser.parse(new FileReader("c:\\sample.json"));
String name = (String) jsonObject.get("name");
long age = (Long) jsonObject.get("age");
JSONArray msg = (JSONArray) jsonObject.get("messages");
System.out.println("Name:"+name);
System.out.println("Age:"+age);
System.out.println("Messages:");
Iterator<String> iterator = msg.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}

Categories

Resources