Java Parse JSON Multidimensional Object element to String - java

I have JSONObject data with multiple object inside.
What i want to do is, make that json to simple hierarchy.
JSON Data
{
"Response": {
"type": "string",
"content": "0000"
},
"Data": {
"item": [
{
"firstname": {
"type": "string",
"content": "Bryan"
},
"lastname": {
"type": "string",
"content": "Adams"
},
"kids": {
"item": [
{
"name": {
"type": "string",
"content": "Tommy"
},
"age": {
"type": "string",
"content": "9"
}
},
{
"name": {
"type": "string",
"content": "Jane"
},
"age": {
"type": "string",
"content": "4"
}
}
]
}
},
{
"firstname": {
"type": "string",
"content": "Joey"
},
"lastname": {
"type": "string",
"content": "Cena"
},
"kids": {
"item": [
{
"name": {
"type": "string",
"content": "Maria"
},
"age": {
"type": "string",
"content": "7"
}
},
{
"name": {
"type": "string",
"content": "Dany"
},
"age": {
"type": "string",
"content": "3"
}
}
]
}
}
]
}
}
My code
package junk;
import java.util.Iterator;
import org.json.JSONException;
import org.json.JSONObject;
/**
*
* #author Agung
*/
class Foo {
private static JSONObject objResponse = new JSONObject();
public static void main(String args[]) throws JSONException {
JSONObject jsonObj = new JSONObject("{\"Response\":{\"type\":\"string\",\"content\":\"0000\"},\"Data\":{\"item\":[{\"firstname\":{\"type\":\"string\",\"content\":\"Bryan\"},\"lastname\":{\"type\":\"string\",\"content\":\"Adams\"},\"kids\":{\"item\":[{\"name\":{\"type\":\"string\",\"content\":\"Tommy\"},\"age\":{\"type\":\"string\",\"content\":\"9\"}},{\"name\":{\"type\":\"string\",\"content\":\"Jane\"},\"age\":{\"type\":\"string\",\"content\":\"4\"}}]}},{\"firstname\":{\"type\":\"string\",\"content\":\"Joey\"},\"lastname\":{\"type\":\"string\",\"content\":\"Cena\"},\"kids\":{\"item\":[{\"name\":{\"type\":\"string\",\"content\":\"Maria\"},\"age\":{\"type\":\"string\",\"content\":\"7\"}},{\"name\":{\"type\":\"string\",\"content\":\"Dany\"},\"age\":{\"type\":\"string\",\"content\":\"3\"}}]}}]}}");
Foo.getResponseContent(jsonObj);
System.out.println(objResponse);
}
private static void getResponseContent(JSONObject jsonObj) throws JSONException {
Iterator<?> keys = jsonObj.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
if (jsonObj.get(key) instanceof JSONObject) {
JSONObject object = jsonObj.getJSONObject(key);
if (object.has("content")) {
String content = (String) object.get("content");
objResponse.put(key, content);
} else {
// if we get here, so the element have multiple node
objResponse.put(key, object);
getResponseContent(object);
}
}
}
}
}
with my code, i get this result :
{
"Response": "0000",
"Data": {
"item": [
{
"firstname": {
"type": "string",
"content": "Bryan"
},
"lastname": {
"type": "string",
"content": "Adams"
},
"kids": {
"item": [
{
"name": {
"type": "string",
"content": "Tommy"
},
"age": {
"type": "int",
"content": "9"
}
},
{
"name": {
"type": "string",
"content": "Jane"
},
"age": {
"type": "int",
"content": "4"
}
}
]
}
},
{
"firstname": {
"type": "string",
"content": "Joey"
},
"lastname": {
"type": "string",
"content": "Cena"
},
"kids": {
"item": [
{
"name": {
"type": "string",
"content": "Maria"
},
"age": {
"type": "int",
"content": "7"
}
},
{
"name": {
"type": "string",
"content": "Dany"
},
"age": {
"type": "int",
"content": "3"
}
}
]
}
}
]
}
}
only work for field with no multiple elements.
but what i wanted result is :
{
"Response": "0000",
"Data": {
"item": [
{
"firstname": "Bryan",
"lastname": "Adams",
"kids": {
"item": [
{
"name": "Tommy",
"age": 9
},
{
"name": "Jane",
"age": 4
}
]
}
},
{
"firstname": "Joey",
"lastname": "Cena",
"kids": {
"item": [
{
"name": "Maria",
"age": 7
},
{
"name": "Dany",
"age": 3
}
]
}
}
]
}
}
i have no idea how to remove objects from Data field.

Here is a program that creates the output in the format you want: like you, I have used recursion, the changes I made were:
I handled arrays
I created a new object to collect the data for a child that does not have the 'content' key.
Here is the code:
package test;
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class TestMain {
public static void main(String args[]) throws Exception {
JSONObject objResponse = new JSONObject();
JSONObject jsonObj = new JSONObject(
"{\"Response\":{\"type\":\"string\",\"content\":\"0000\"},\"Data\":{\"item\":[{\"firstname\":{\"type\":\"string\",\"content\":\"Bryan\"},\"lastname\":{\"type\":\"string\",\"content\":\"Adams\"},\"kids\":{\"item\":[{\"name\":{\"type\":\"string\",\"content\":\"Tommy\"},\"age\":{\"type\":\"string\",\"content\":\"9\"}},{\"name\":{\"type\":\"string\",\"content\":\"Jane\"},\"age\":{\"type\":\"string\",\"content\":\"4\"}}]}},{\"firstname\":{\"type\":\"string\",\"content\":\"Joey\"},\"lastname\":{\"type\":\"string\",\"content\":\"Cena\"},\"kids\":{\"item\":[{\"name\":{\"type\":\"string\",\"content\":\"Maria\"},\"age\":{\"type\":\"string\",\"content\":\"7\"}},{\"name\":{\"type\":\"string\",\"content\":\"Dany\"},\"age\":{\"type\":\"string\",\"content\":\"3\"}}]}}]}}");
getResponseContent(jsonObj, objResponse);
System.out.println(objResponse.toString(2));
}
private static void getResponseContent(JSONObject jsonObj, JSONObject objResponse) throws JSONException {
Iterator<?> keys = jsonObj.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
JSONObject child = jsonObj.optJSONObject(key);
if (child != null) {
if (child.has("content")) {
objResponse.put(key, child.get("content"));
} else {
JSONObject responseChild = new JSONObject();
objResponse.put(key, responseChild);
getResponseContent(child, responseChild);
}
} else {
JSONArray children = jsonObj.optJSONArray(key);
if (children != null) {
JSONArray responseChildren = new JSONArray();
objResponse.put(key, responseChildren);
for (int i = 0; i < children.length(); i++) {
child = children.getJSONObject(i);
JSONObject responseChild = new JSONObject();
responseChildren.put(responseChild);
getResponseContent(child, responseChild);
}
}
}
}
}
}
Here is its output:
{
"Response": "0000",
"Data": {"item": [
{
"firstname": "Bryan",
"lastname": "Adams",
"kids": {"item": [
{
"name": "Tommy",
"age": "9"
},
{
"name": "Jane",
"age": "4"
}
]}
},
{
"firstname": "Joey",
"lastname": "Cena",
"kids": {"item": [
{
"name": "Maria",
"age": "7"
},
{
"name": "Dany",
"age": "3"
}
]}
}
]}
}

Related

JOLT shift transformation: filter by inner value of a property (not the name) - only some properties

I am trying to transform a JSON using Jolt transformation looking for some input here.
I am trying to filter by the inner value of the attribute.
My goal is to get an array that contains only the items with the typeName 'xx'. But not all the item object, only some of the fields
{
"id": "11_1",
"action": "add",
"payment": {
"paied": true,
"coin": "dollar"
},
"type": {
"id": "11_1_xx",
"typeName": "xx"
},
"details": {
"place": {
"id": "123",
"name": "xx"
},
"status": {
"id": "123",
"name": "xx"
}
}
}
Here is my input and expected output:
Input:
{
"id": 11,
"item": [
{
"id": "11_1",
"action": "add",
"payment": {
"paied": true,
"coin": "dollar"
},
"type": {
"id": "11_1_xx",
"typeName": "xx",
"typeGroup": "xx",
"typeValue": "xx"
},
"details": {
"place": {
"id": "123",
"name": "xx"
},
"status": {
"id": "123",
"name": "xx"
},
"reason": {
"id": "123",
"name": "xx"
}
},
"item": [
{
"id": "11_1_1",
"action": "add",
"payment": {
"paied": true,
"coin": "dollar"
},
"type": {
"id": "11_1_1_zz",
"typeName": "zz",
"typeGroup": "zz",
"typeValue": "zz"
},
"details": {
"place": {
"id": "123",
"name": "xx"
},
"status": {
"id": "123",
"name": "xx"
},
"reason": {
"id": "123",
"name": "xx"
}
},
"item": [
{
"id": "11_1_1_1",
"action": "add",
"payment": {
"paied": true,
"coin": "NIS"
},
"type": {
"id": "11_1_1_1_xx",
"typeName": "xx",
"typeGroup": "xx",
"typeValue": "xx"
},
"details": {
"place": {
"id": "123",
"name": "xx"
},
"status": {
"id": "123",
"name": "xx"
},
"reason": {
"id": "123",
"name": "xx"
}
}
}
]
},
{
"id": "11_1_2",
"action": "add",
"payment": {
"paied": false,
"coin": "dollar"
},
"type": {
"id": "11_1_2_xx",
"typeName": "xx",
"typeGroup": "xx",
"typeValue": "xx"
},
"details": {
"place": {
"id": "123",
"name": "xx"
},
"status": {
"id": "123",
"name": "xx"
},
"reason": {
"id": "123",
"name": "xx"
}
},
"item": [
{
"id": "11_1_2_1",
"action": "add",
"payment": {
"paied": false,
"coin": "NIS"
},
"type": {
"id": "11_1_2_1_zz",
"typeName": "zz",
"typeGroup": "zz",
"typeValue": "zz"
},
"details": {
"place": {
"id": "123",
"name": "xx"
},
"status": {
"id": "123",
"name": "xx"
},
"reason": {
"id": "123",
"name": "xx"
}
}
}
]
}
]
}
]
}
Expected output:
[
{
"id": "11_1",
"action": "add",
"payment": {
"paied": true,
"coin": "dollar"
},
"type": {
"id": "11_1_xx",
"typeName": "xx"
},
"details": {
"place": {
"id": "123",
"name": "xx"
},
"status": {
"id": "123",
"name": "xx"
}
}
},
{
"id": "11_1_1_1",
"action": "add",
"payment": {
"paied": true,
"coin": "NIS"
},
"type": {
"id": "11_1_1_1_xx",
"typeName": "xx"
},
"details": {
"place": {
"id": "123",
"name": "xx"
},
"status": {
"id": "123",
"name": "xx"
}
}
},
{
"id": "11_1_2",
"action": "add",
"payment": {
"paied": false,
"coin": "dollar"
},
"type": {
"id": "11_1_2_xx",
"typeName": "xx"
},
"details": {
"place": {
"id": "123",
"name": "xx"
},
"status": {
"id": "123",
"name": "xx"
}
}
}
]
Can you please help me to write a simple spec that will do this?
You can use the following explained spec
[
{
// Determine all key-value pairs partitioned under the main value and type.typeValue combinations
"operation": "shift",
"spec": {
"item": {
"*": {
"item": {
"*": {
"item": {
"*": {
"type": {
"#(1,id)": "#(2,id).#(1,typeName).id", //traverse } character twice in order to reach the main id of the object
"#(1,action)": "#(2,id).#(1,typeName).action",
"*": "#(2,id).#(1,typeName).&1.&" // &1 replicates "type" key, & does the leaf value
},
"*": "#(1,id).#(1,type.typeName).&"
}
},
"type": {
"#(1,id)": "#(2,id).#(1,typeName).id",
"#(1,action)": "#(2,id).#(1,typeName).action",
"*": "#(2,id).#(1,typeName).&1.&"
},
"*": "#(1,id).#(1,type.typeName).&"
}
},
"type": {
"#(1,id)": "#(2,id).#(1,typeName).id",
"#(1,action)": "#(2,id).#(1,typeName).action",
"*": "#(2,id).#(1,typeName).&1.&"
},
"*": "#(1,id).#(1,type.typeName).&"
}
}
}
},
{
// Filter out by the desired value(in this case it's "xx")
"operation": "shift",
"spec": {
"*": {
"xx": ""
}
}
},
{
// Get rid of same repeating components of id and action arrays
"operation": "cardinality",
"spec": {
"*": {
"id": "ONE",
"action": "ONE"
}
}
},
{
// Get rid of undesired attributes
"operation": "remove",
"spec": {
"*": {
"type": {
"typeGroup": "",
"typeValue": ""
},
"det*": {
"reason": ""
}
}
}
}
]
You may try library Josson. Function map() build a new ObjectNode. Function field() modify the current ObjectNode and can be used to remove fields. The transformation statement is short and easy to understand.
https://github.com/octomix/josson
Josson josson = Josson.fromJsonString(inputJSON);
JsonNode node = josson.getNode(
"cumulateCollect(" +
" [type.typeName='xx']" + // filter
" .field(type.map(id, typeName)" + // need "type.id" and "type.typeName"
" ,details.field(reason:)" + // remove "details.reason"
" ,item:)" + // remove "item"
" ,item)"); // next round
System.out.println(node.toPrettyString());

Elasticsearch:Getting nested object under path is not of nested type

I am new to the Elastic search world.Basically I am trying to retrieve the nested objects based on the ID.This is the JSON representation of my document.
{
"_index": "xyz",
"_type": "abc",
"_id": "12",
"_version": 1,
"found": true,
"_source":
{
"lastModifiedBy": "12",
"lastModifiedDate": "2015-12-31T19:45:29.493Z",
"profile":
[
{
"type": "nested",
"views":
[
{
"type": "nested",
"id": "view1",
"name": "view1",
"properties":
[
{
"name": "default",
"value": false
}
],
"widgets":
[
{
"type": "nested",
"id": "graph",
"name": "graph",
"elementId": "ui_graph",
"properties":
[
{
"name": "currency",
"value": "YEN"
}
]
}
]
}
} ] } ]
I am trying to get the widgets based on the view id.This is the my search query.
"query" : {
"term" : {
"_id" : "12"
}
},
"post_filter" : {
"nested" : {
"query" : {
"filtered" : {
"query" : {
"match_all" : { }
},
"filter" : {
"term" : {
"profile.views.id" : "view1"
}
}
}
},
"path" : "profile.views"
}
}
}
I am not sure what is wrong here.But getting "nested object under path [profile.views] is not of nested type]".
Below is my mapping structure
{
"xyz": {
"mappings": {
"abc": {
"properties": {
"lastModifiedBy": {
"type": "string"
},
"lastModifiedDate": {
"type": "date",
"format": "dateOptionalTime"
},
"name": {
"type": "string"
},
"profile": {
"properties": {
"lastModifiedBy": {
"type": "string"
},
"lastModifiedDate": {
"type": "date",
"format": "dateOptionalTime"
},
"type": {
"type": "string"
},
"views": {
"properties": {
"id": {
"type": "string"
},
"isDefault": {
"type": "boolean"
},
"name": {
"type": "string"
},
"properties": {
"properties": {
"name": {
"type": "string"
},
"type": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"type": {
"type": "string"
},
"viewId": {
"type": "string"
},
"widgets": {
"properties": {
"elementId": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"properties": {
"properties": {
"name": {
"type": "string"
},
"type": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"type": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
}
}
Please help!
You are getting the error because you have not specified type as nested for profile and views. Refer to the Docs for how to created nested objects . You should be defining type as nested for every nested object like this
{
"xyz": {
"mappings": {
"abc": {
"properties": {
"lastModifiedBy": {
"type": "string"
},
"lastModifiedDate": {
"type": "date",
"format": "dateOptionalTime"
},
"name": {
"type": "string"
},
"profile": {
"type": "nested", <--- here, you need this for every nested object
"properties": {
"lastModifiedBy": {
"type": "string"
},
"lastModifiedDate": {
"type": "date",
"format": "dateOptionalTime"
},
"type": {
"type": "string"
},
"views": {
"type": "nested",
"properties": {
"id": {
"type": "string"
},
"isDefault": {
"type": "boolean"
},
"name": {
"type": "string"
},
"properties": {
"type": "nested",
"properties": {
"name": {
"type": "string"
},
"type": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"type": {
"type": "string"
},
"viewId": {
"type": "string"
},
"widgets": {
"type": "nested",
"properties": {
"elementId": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"properties": {
"type": "nested",
"properties": {
"name": {
"type": "string"
},
"type": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"type": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
}
}
Hope this helps!!

AVRO GenericDatumWriter Fails when writing a ComplexType datum

Here is my scenario:
I have a schema for my class that is validated by Avro:
{
"type": "record",
"name": "MyCLass",
"namespace": "com.somepackage",
"fields": [
{
"name": "attributes",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "KeyValuePair",
"fields": [
{
"name": "key",
"type": "string"
},
{
"name": "value",
"type": "string"
}
]
},
"java-class": "java.util.List"
}
},
{
"name": "someString",
"type": "string"
},
{
"name": "myclass1",
"type": {
"type": "record",
"name": "MyClass1",
"fields": [
{
"name": "attributes",
"type": {
"type": "record",
"name": "ArrayOfKeyValuePair",
"fields": [
{
"name": "item",
"type": {
"type": "array",
"items": "KeyValuePair",
"java-class": "java.util.List"
}
}
]
}
},
{
"name": "labels",
"type": {
"type": "record",
"name": "ArrayOfXsdString",
"fields": [
{
"name": "item",
"type": {
"type": "array",
"items": "string",
"java-class": "java.util.List"
}
}
]
}
},
{
"name": "uniqueID",
"type": "string"
}
]
}
},
{
"name": "MyClass2",
"type": {
"type": "record",
"name": "MyClass2",
"fields": [
{
"name": "attributes",
"type": "ArrayOfKeyValuePair"
},
{
"name": "someString",
"type": "string"
},
{
"name": "someLabel",
"type": "ArrayOfXsdString"
},
{
"name": "someId",
"type": "string"
}
]
}
}
]
}
This schema was generated with `GenericRecord obj = new GenericData.Record(ReflectData.get().getSchema(MyClass.class));
next I build the list of 4 parameters that the obj expects in it's values list:
KeyValuePair kv1 = new KeyValuePair();
kv1.setKey("key1");
kv1.setValue("val1");
KeyValuePair kv2 = new KeyValuePair();
kv2.setKey("key2");
kv2.setValue("val2");
List<KeyValuePair> attr = new ArrayList<KeyValuePair>();
attr.add(kv1);
attr.add(kv2);
ArrayOfKeyValuePair arrKV = new ArrayOfKeyValuePair();
arrKV.getItem().add(kv1);
MyClass1 ud = new MyClass1();
ud.setAttributes(arrKV);
ud.setUniqueID("SomeID");
MyCLass2 sd = new MyCLass2();
sd.setAttributes(arrKV);
sd.setExternalCaseID("SomeID");
sd.setUniqueID("SomeId");
obj.put("attributes", attr);
obj.put("workFlowName", "Nume workflow");
obj.put("userDescriptor", ud);
obj.put("subscriberDescriptor", sd);
And when I try:
ByteArrayOutputStream out = new ByteArrayOutputStream();
DatumWriter<GenericRecord> writerS = new GenericDatumWriter<GenericRecord>(schemaMentionedAbove);
Encoder encoder = EncoderFactory.get().binaryEncoder(out, null);
writerS.write(obj, encoder);
encoder.flush();
out.close();
The code fails at line: writerS.write(obj, encoder); with error:
KeyValuePair cannot be cast to org.apache.avro.generic.IndexedRecord
KeyValuePair class is a simple class with 2 fields: String key, String value.
After debugging I can see that DatumWriter fails on iterating through the first "attributes" array of records.
Any help appreciated! Thanks

Setting a dynamic date format in Elastic Search

I am new to Elastic Search.
I have a User mapping and associated with the User is a Nested Object extraDataValues. In this object is the id, a string value and another nested object. For example:
"extraDataValues": [
{
"id": 1,
"value": "01/01/2016 00:00:00",
"id": 10,
"label": "Metadata Date",
"displayable": true
},
},
{
"id": 2,
"value": "aaaa",
"id": 11,
"label": "Metadata TextBox",
"displayable": true
},
}
],
As you can see, value field can be a date or a normal string. The problem arises here, I want to be able to sort this value given that it could be either a date or a normal string. Moreover, the date can be in two formats: "dd/MM/yyyy HH:mm:ss", "dd/MM/yyyy". How can I achieve this firstly with Elastic Search (so I can understand the theory) and then Java?
I have tried adding "dynamic_date_formats" : ["dd/MM/yyyy HH:mm:ss", "dd/MM/yyyy"]
to no avail.
The mapping for the Users is:
User Mapping Document
{
"User": {
"properties": {
"fullName": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
},
"username": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
},
"email": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
},
"firstName": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
},
"surname": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
},
"id": {
"type": "long"
},
"extraDataValues": {
"type": "nested",
"dynamic_date_formats" : ["dd/MM/yyyy HH:mm:ss", "dd/MM/yyyy"],
"properties": {
"extraDataValueObject": {
"properties": {
"id": {
"type": "long"
},
"label": {
"type": "string"
},
"displayable": {
"type": "boolean"
}
}
},
"value": {
"type": "string",
"index": "not_analyzed",
"fields": {
"raw_lower_case": {
"type": "string",
"analyzer": "case_insensitive"
}
}
}
}
}
}
}
}
You can't do that the way you are trying to do it. dynamic_date_formats are used only for dynamically added date fields, not for date fields that you specify in your mapping (from the documentation).
What I would suggest trying out is this mapping:
"value": {
"type": "string",
"fields": {
"date1": {
"type": "date",
"format": "dd/MM/yyyy HH:mm:ss",
"ignore_malformed": "true"
},
"date2": {
"type": "date",
"format": "dd/MM/yyyy",
"ignore_malformed": "true"
}
}
}
Where you have a field which is string (for the string type part of the value) and for it you define two subfields each with a different date format. It's imperative to have for them "ignore_malformed": "true" in case you really have a string instead of a date coming in.
In this way you can index this:
POST /my_index/user/1
{
"value": "aaa"
}
POST /my_index/user/2
{
"value": "01/01/2016 00:00:00"
}
POST /my_index/user/3
{
"value": "02/02/2016"
}
And you could differentiate between which type of date or string was indexed like this in a query:
"query": {
"filtered": {
"filter": {
"exists": {
"field": "value.date2"
}
}
}
}
If ES was able to index something under value.date2 then you get that document back. The same goes for value.date1, of course.

JSON for constructing multilevel tree

I wanted to form JSON like this:
{
"Schedule": [
{
"id": "A",
"name": "Summary",
"ischild": "1",
"level1": [
{
"id": "A.1",
"name": "A.1",
"ischild": "1",
"level2": [
{
"id": "A.1.a",
"name": "Income Statement",
"ischild": "0"
},
{
"id": "A.1.b",
"name": "Balance Sheet",
"ischild": "0"
},
{
"id": "A.1.c",
"name": "A.1.c",
"ischild": "1",
"level3": [
{
"id": "A.1.c.1",
"name": "General RWA",
"ischild": "0"
},
{
"id": "A.1.c.2",
"name": "Standardized RWA",
"ischild": "0"
},
{
"id": "A.1.c.3",
"name": "Advanced RWA",
"ischild": "0"
}
]
}
]
}
]
}
]
}
But my code is giving below output:
{
"Schedule": [
{
"name": "Summary",
"ischild": "1",
"id": "A",
"N_LEVEL": "1"
},
{
"name": "A.1",
"ischild": "1",
"id": "A.1",
"N_LEVEL": "2"
},
{
"name": "Income Statement",
"ischild": "0",
"id": "A.1.a",
"N_LEVEL": "3"
},
{
"name": "Balance Sheet",
"ischild": "0",
"id": "A.1.b",
"N_LEVEL": "3"
},
{
"name": "A.1.c",
"ischild": "1",
"id": "A.1.c",
"N_LEVEL": "3"
},
{
"name": "General RWA",
"ischild": "0",
"id": "A.1.c.1",
"N_LEVEL": "4"
},
{
"name": "Standardized RWA",
"ischild": "0",
"id": "A.1.c.2",
"N_LEVEL": "4"
},
{
"name": "Advanced RWA",
"ischild": "0",
"id": "A.1.c.3",
"N_LEVEL": "4"
}
]
}
Here is my code:
public static String getJSONFromResultSet(ResultSet rs,String keyName)
{
System.out.println(" in getJSONFromResultSet method");
Map json = new HashMap();
List list = new ArrayList();
if(rs!=null)
{
try
{
ResultSetMetaData metaData = rs.getMetaData();
while(rs.next())
{
Map<String,Object> columnMap = new HashMap<String, Object>();
for(int columnIndex=1;columnIndex<=metaData.getColumnCount();columnIndex++)
{
if(rs.getString(metaData.getColumnName(columnIndex))!=null)
columnMap.put(metaData.getColumnLabel(columnIndex),rs.getString(metaData.getColumnName(columnIndex)));
else
columnMap.put(metaData.getColumnLabel(columnIndex), "");
}
list.add(columnMap);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
json.put(keyName, list);
}
return JSONValue.toJSONString(json);
I think your target structure could be better if it's names didn't change on every level. The level number is a value not a key. ischild makes no sense either, I think this is isNotALeaf, well that can be worked out, so leave that off too, so we have:
{
"id": "A",
"name": "Summary",
"level": "1",
"children": [
{
"id": "A.1",
"name": "A.1",
"level": "2",
"children": [
{
"id": "A.1.a",
"name": "Income Statement",
"level": "3"
},
{
"id": "A.1.b",
"name": "Balance Sheet",
"level": "3"
}
]
}
}
Then generate a self-referencing class with based on that for use in GSon:
package com.example;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
#Generated("org.jsonschema2pojo")
public class Child {
#Expose
private String id;
#Expose
private String name;
#Expose
private String level;
#Expose
private List<Child> children = new ArrayList<Child>();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public List<Child_> getChildren() {
return children;
}
public void setChildren(List<Child> children) {
this.children = children;
}
}

Categories