I have a JSON object and want to show the fields hierarchically.
checkedTreeSelectionDialog.setInput(jsonObject);
Inside the getchildren() method of the JsonContentProvider class, I am parsing the json object
private void getChildrenForJson(final Object object) {
final JSONObject jsonObject = (JSONObject) object;
for (final Object objct : jsonObject.keySet()) {
try {
if (jsonObject.get(objct) instanceof JSONArray) {
getArray(jsonObject.get(objct));
} else {
if (jsonObject.get(objct) instanceof JSONObject) {
getChildrenForJson(jsonObject.get(objct));
}
}
However, the returned fields are not coming hierarchically.
How can I get those fields hierarchically?
function sortObject(o) {
var sorted = {},
key, a = [];
for (key in o) {
if (o.hasOwnProperty(key)) {
a.push(key);
}
}
a.sort();
for (key = 0; key < a.length; key++) {
sorted[a[key]] = o[a[key]];
}
return sorted;
}
private void getChildrenForJson(final Object object) {
final JSONObject jsonObject = (JSONObject) object;
for (final Object objct : jsonObject.keySet()) {
try {
if (jsonObject.get(objct) instanceof JSONArray) {
var q = getArray(jsonObject.get(objct));
var p = sortObject(q);
console.log(p);
} else {
if (jsonObject.get(objct) instanceof JSONObject) {
var q =getChildrenForJson(jsonObject.get(objct));
var p = sortObject(q);
console.log(p);
}
}
This is what you were expecting , I hope !
Related
I have a problem with parsing an JSON object inside a JSON object, this is how my JSON file looks like:
{
"index":1,
"name":"Peter",
"status":"Student",
"traditional":true,
"address":
{
"street":"Street1",
"city":"City1",
"ZIP":11000
},
"phoneNumbers":[1231123,123111],
"role":"Programmer"
}
And the parseJson() method:
public String parseJson() {
Integer rbr = 0;
StringReader stringReader = new StringReader(jsonStr);
JsonParser jsonParser = Json.createParser(stringReader);
Map<String, Object> jsonMap = new HashMap<>();
String jsonKeyNm = null;
Object jsonVal = null;
while (jsonParser.hasNext()) {
JsonParser.Event event = jsonParser.next();
if (event.equals(Event.KEY_NAME)) {
jsonKeyNm = jsonParser.getString();
}
else if (event.equals(Event.VALUE_STRING)) {
jsonVal = jsonParser.getString();
}
else if (event.equals(Event.VALUE_NUMBER)) {
jsonVal = jsonParser.getInt();
}
**else if (event.equals(Event.START_OBJECT)) {
if(rbr == 0){
//The rbr is used, since when first time when it starts going through json it will be an *START_OBJECT* event too.
rbr++;
continue;
}
jsonVal = jsonParser.getClass();
}**
else if (event.equals(Event.VALUE_TRUE)) {
jsonVal = (Boolean) true;
}
else if (event.equals(Event.VALUE_FALSE)) {
jsonVal = (Boolean) false;
}
**else if (event.equals(Event.START_ARRAY)) {
jsonVal = event.VALUE_STRING;
}**
else if (event.equals(Event.END_ARRAY)) {
jsonVal = event.VALUE_STRING;
}
jsonMap.put(jsonKeyNm, jsonVal);
}
student.setName((String)jsonMap.get("name"));
student.setIndex((Integer)jsonMap.get("index"));
student.setStatus((String)jsonMap.get("status"));
student.setTraditional((Boolean)jsonMap.get("traditional"));
Address address1 = (Address) jsonMap.get("address");
// Tried this too
//Address address =(Address) jsonMap.get("address").getClass().cast(Adress.class);
}
What it actually returns me when I execute jsonMap.get("address") is Java.util.class type. And I am stuck again, can't manage to extract any data from that.
Any help how I could accept and work with the object I get or any other way I could use to read all the data properly?
Also I have a problem reading Array from JSON, since the methods that JsonParser has are only:
.getBigDecimail()
.getInt()
.getLocation()
.getLong()
.getString()
.getClass()
I have to say that I have done it using The JSON-P object model API, but for my project for my university they are asking me to work with The JSON-P streaming API.
Thanks in advance!
public static String parseJson(InputStream in) {
String key = "student";
Deque<String> stack = new LinkedList<>();
Map<String, Object> map = new HashMap<>();
Object obj = null;
JsonParser parser = Json.createParser(in);
while (parser.hasNext()) {
Event event = parser.next();
if (event == Event.START_OBJECT) {
map.putIfAbsent(key, new HashMap<>());
obj = map.get(key);
stack.push(key);
} else if (event == Event.END_OBJECT) {
stack.pop();
obj = stack.isEmpty() ? null : map.get(stack.element());
} else if (event == Event.START_ARRAY) {
Object tmp = new ArrayList<>();
setValue(obj, key, tmp);
obj = tmp;
} else if (event == Event.END_ARRAY)
obj = stack.isEmpty() ? null : map.get(stack.element());
else if (event == Event.KEY_NAME)
key = parser.getString().toLowerCase();
else {
Object value = null;
if (event == Event.VALUE_STRING)
value = parser.getString();
else if (event == Event.VALUE_NUMBER)
value = parser.getInt();
else if (event == Event.VALUE_TRUE)
value = true;
else if (event == Event.VALUE_FALSE)
value = false;
setValue(obj, key, value);
}
}
Student student = new Student();
student.setName(getMapValue(map, "student", "name"));
student.setIndex(getMapValue(map, "student", "index"));
student.setStatus(getMapValue(map, "student", "status"));
student.setTraditional(getMapValue(map, "student", "traditional"));
student.setRole(getMapValue(map, "student", "role"));
student.setPhoneNumbers(getMapValue(map, "student", "phoneNumbers"));
Address address = new Address();
address.setStreet(getMapValue(map, "address", "street"));
address.setCity(getMapValue(map, "address", "city"));
address.setZip(getMapValue(map, "address", "zip"));
return "";
}
private static void setValue(Object obj, String key, Object value) {
if (obj instanceof Map)
((Map<String, Object>)obj).put(key, value);
else
((Collection<Object>)obj).add(value);
}
private static <T> T getMapValue(Map<String, Object> map, String obj, String key) {
Map<String, Object> m = (Map<String, Object>)map.get(obj.toLowerCase());
return m != null ? (T)m.get(key.toLowerCase()) : null;
}
I have a program that reads in a simple JSON file and manipulates the data. I then store this data in trees (albeit badly). I have a problem where arguments can longs e.g {1,2}, longs and variables e.g {1,x2}, or variables with other variables e.g. {x1,x2}.
I have been able to retrieve the variables from the JSONArray. The problem arises when I have a variable and a value. I can't for the life of me figure out how to deal with such an occurrence. I apologise for the excessive use of try-catch operations. If anyone could help me solve this issue, it would be much appreciated.
public class program {
public static void main(String[] args) throws IOException {
File file = new File();
File outputfile = new File();
PrintWriter pw = new PrintWriter(new BufferedWriter(new
FileWriter(outputfile, true)));
JSONParser parser = new JSONParser();
try {
// creates object of parsed file
Object object = parser.parse(new FileReader(file));
// casts object to jsonObject
JSONObject jsonObject = (JSONObject) object;
// gets declaration-list JSONArray from the object created.
JSONArray jsonArray = (JSONArray) jsonObject.get("declaration-list");
// Surrounding this in a try-catch would allow me to deal with the
// different value cases unlike the frist time i wrote it
try {
/*
* iterator to cycle through the array. Made the mistake last
* time of continuously calling a method
*/
Iterator iterator = jsonArray.iterator();
while (iterator.hasNext()) {
JSONObject jo = (JSONObject) iterator.next();
String variableName = (String) jo.get("declared-variable");
MyTreeNode<String> root = new MyTreeNode<>(variableName);
try {
long value = (long) jo.get("value");
MyTreeNode<Long> child1 = new MyTreeNode(value);
System.out.println(root.getData());
root.addChild(child1);
for (MyTreeNode node : root.getChildren()) {
System.out.println(node.getData());
}
test.put(variableName, value);
// numPrint(test, variableName, pw);
} catch (Exception e) {
final JSONObject jsonValue = (JSONObject) jo.get("value");
final String operator = (String) jsonValue.get("operator");
final JSONArray arguments = (JSONArray) jsonValue.get("arguments");
ArrayList values[] = new ArrayList[arguments.size()];
if (operator.equals("set")) {
for(int i = 0; i < arguments.size(); i++){
try{
//prints nested variables
JSONObject jtest = (JSONObject) arguments.get(i);
String varval = (String) jtest.get("variable");
System.out.println(varval);
}catch(Exception g){
}
}
MyTreeNode<myObject> test1 = new MyTreeNode(new myObject(operator, arguments));
root.addChild(test1);
for (MyTreeNode node : root.getChildren()) {
System.out.print(root.getData());
System.out.print(" = ");
System.out.println(node.getData());
}
}
if (operator.equals("pair")) {
MyTreeNode<myObject> test1 = new MyTreeNode(new myObject(operator, arguments));
root.addChild(test1);
for (MyTreeNode node : root.getChildren()) {
System.out.print(root.getData() + " = ");
System.out.println(node.getData());
}
}
}
}
} catch (Exception e) {
System.out.println("oops");
}
} catch (FileNotFoundException e) {
System.out.println("Input file not found");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
System.out.println("File was not parsed");
e.printStackTrace();
}
pw.flush();
pw.close();
}
}
class MyTreeNode<T> {
private T data = null;
private List<MyTreeNode> children = new ArrayList<>();
private MyTreeNode parent = null;
public MyTreeNode(T data) {
this.data = data;
}
public void addChild(MyTreeNode child) {
child.setParent(this);
this.children.add(child);
}
public void addChild(T data) {
MyTreeNode<T> newChild = new MyTreeNode<>(data);
newChild.setParent(this);
children.add(newChild);
}
public void addChildren(List<MyTreeNode> children) {
for (MyTreeNode t : children) {
t.setParent(this);
}
this.children.addAll(children);
}
public List<MyTreeNode> getChildren() {
return children;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
private void setParent(MyTreeNode parent) {
this.parent = parent;
}
public MyTreeNode getParent() {
return parent;
}
}
class myObject {
String operator;
JSONArray arguments;
public myObject(String operator, JSONArray arguments) {
this.operator = operator;
this.arguments = arguments;
}
public JSONArray get() {
return arguments;
}
public String toString() {
if (arguments.size() == 0) {
return "{}";
}
if (operator.equals("pair")) {
return "(" + arguments.get(0) + "," + arguments.get(1) + ")";
} else if (operator.equals("set")) {
String concat = "{" + arguments.get(0);
for (int i = 1; i < arguments.size(); i++) {
concat += "," + arguments.get(i);
}
return concat += "}";
}
return "wot";
}
}
In order to process the JSONArray, I suggest that you create a method which checks the type of the object first and then delegates the processing to other specialised methods based on its type.
This will allow you re-use the code in case you have arrays in arrays and also to navigate through the JSON tree.
Something along these lines:
private static void processArray(JSONArray jsonArray) {
jsonArray.forEach(o -> {
if (o instanceof Number) {
processNumber((Number) o);
} else if (o instanceof JSONObject) {
process((JSONObject) o);
} else if (o instanceof String) {
process((String) o);
} else if (o instanceof JSONArray) {
processArray((JSONArray) o); // recursive call here.
}
});
}
Other methods would look like:
private static void process(String o) {
System.out.println(o); // just an example
}
public static void processNumber(Number number) {
System.out.println(number); // just an example
}
And the most complex would be the one for processing objects:
private static void process(JSONObject o) {
o.forEach((s, o1) -> {
System.out.println(s);
if (o1 instanceof Number) {
processNumber((Number) o1);
} else if (o1 instanceof JSONObject) {
process((JSONObject) o1); // recursion
} else if (o1 instanceof String) {
process((String) o1);
} else if (o1 instanceof JSONArray) {
processArray((JSONArray) o1);
}
});
}
This method would also be recursive. With this type of approach you can navigate through all objects in the tree.
Update:
If you want to process JSON like:
{
"declared-variable": "x17",
"value": {
"operator": "set",
"arguments": [
1,
2,
{
"variable": "x8"
}
]
}
}
you can do so by creating a main method similar to this one:
public static void main(String[] args) throws IOException, ParseException {
JSONParser jsonParser = new JSONParser(JSONParser.MODE_JSON_SIMPLE);
try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("array_mixed.json")) {
Object obj = jsonParser.parse(in);
if (obj instanceof JSONArray) {
processArray((JSONArray) obj);
}
else if(obj instanceof Object) {
process((JSONObject) obj);
}
}
}
This main method together with the other methods described can at least print out all the elements in the JSON.
You should be able to at least print out the following in the case of the specified JSON above:
declared-variable
x17
value
arguments
1
2
variable
x8
operator
set
During automation test run, I come across JsonObject like followin, let's call it jsonObject.
{
"434": {
"Test1": {
"id": "0001",
"Name": "John"
}
},
"435": {
"Test2": {
"id": "0002",
"Name": "John"
}
}
}
I want to retrieve JsonObject for Test1 and Test2. I can retrieve it like:
jsonObject.getJsonObject("434").getJsonObject("Test1");
jsonObject.getJsonObject("435").getJsonObject("Test2");
But values 434 and 435 are not constants. When I re-run test, this time those could be some different numbers. Hence I don't know what could be there next time instead of 434 and 435
Is there any way, I can get JsonObject of Test1 and Test2 irrespective of 434 and 435 (something like jsonObject.someMethod("Test1");)?
I'm using javax.json library.
You can use jsonObject.keys() to get an iterator of all property names in current JSON object. This will allow you to do something like this:
Iterable<String> keys = () -> jsonObject.keys();
List<JSONObject> nestedFilteredObjects = stream(keys.spliterator(), false)
.filter(key -> jsonObject.getJSONObject(key).has("Test"))
.map(key -> jsonObject.getJSONObject(key))
.collect(toList());
Of course you still need to add try-catches for the json exceptions and consider what happens when the property is not a json object (getJSONObject will throw the exception).
Something like the code below should do. Please keep in mind that I did not test it and you can adapt it more to your needs - I don't know what possible jsons you may have in your tests:
private static List<JSONObject> getNestedTestObjects(JSONObject jsonObject) {
#SuppressWarnings("Convert2MethodRef")
Iterable<String> keys = () -> jsonObject.keys();
return stream(keys.spliterator(), false)
.map(key -> object(jsonObject, key))
.filter(object -> object instanceof JSONObject)
.map(object -> (JSONObject) object)
.filter(object -> object.has("Test"))
.map(object -> object(object, "Test"))
.filter(object -> object instanceof JSONObject)
.map(object -> (JSONObject) object)
.collect(toList());
}
private static Object object(JSONObject jsonObject, String key) {
try {
return jsonObject.get(key);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
You can retrieve your target object by passing in the key you are searching for. The method will handle traveling down to each child object to find the matching key. It will return the first match.
Also, you can retrieve all nested JSON objects at a desired depth by using a recursive routine as seen below. You choose the level and the method will add each JsonObject to a results list. The list is printed at the end.
import java.io.*;
import java.util.*;
import javax.json.*;
import javax.json.stream.JsonGenerator;
public class JsonSearchUtilities {
public static void main(String[] args) {
JsonObject jsonObj = readJson("data.json");
// Search for a JSON object by its key.
System.out.println("===================\nSearch by Key\n===================");
searchByKey(jsonObj, "Test2");
// Search for a JSON objects by depth.
System.out.println("\n===================\nSearch by Depth\n===================\n");
searchFullDepth(jsonObj);
}
// ========================================================================
// Main Routines
// ========================================================================
public static void searchByKey(JsonObject jsonObj, String key) {
JsonObject json = getJsonByKey(jsonObj, key);
String jsonStr = prettyPrint(json);
System.out.println(jsonStr);
}
public static void searchFullDepth(JsonObject jsonObj) {
JsonArray jsonArr = null;
int depth = 0;
do {
jsonArr = getNestedObjects(jsonObj, depth);
String jsonStr = prettyPrint(jsonArr);
System.out.printf("Depth = %d%n%s%s%n%n", depth, "---------", jsonStr);
depth++;
} while (jsonArr != null && !jsonArr.isEmpty());
}
// ========================================================================
// Key Search - Search by key
// ========================================================================
public static JsonObject getJsonByKey(JsonObject jsonObj, String search) {
return getJsonByKey(jsonObj, search, 10);
}
public static JsonObject getJsonByKey(JsonObject jsonObj, String search, int maxDepth) {
return getJsonByKey(jsonObj, search, maxDepth, 0);
}
/** #private Inner recursive call. */
private static JsonObject getJsonByKey(JsonObject jsonObj, String search, int maxDepth, int level) {
if (level < maxDepth && jsonObj != null) {
Object child = null;
for (String key : jsonObj.keySet()) {
child = jsonObj.get(key);
if (child instanceof JsonObject) {
if (key.equals(search)) {
return (JsonObject) child;
}
}
}
return getJsonByKey((JsonObject) child, search, maxDepth, level + 1);
}
return null;
}
// ========================================================================
// Depth Search - Search by depth
// ========================================================================
public static JsonArray getNestedObjects(JsonObject jsonObj, int depth) {
JsonArrayBuilder builder = Json.createArrayBuilder();
getNestedObjects(jsonObj, builder, depth);
return builder.build();
}
/** #private Inner recursive call. */
private static void getNestedObjects(JsonObject jsonObj, JsonArrayBuilder builder, int level) {
if (level == 0) {
builder.add(jsonObj);
}
if (jsonObj != null) {
for (String key : jsonObj.keySet()) {
Object child = jsonObj.get(key);
if (child instanceof JsonObject) {
getNestedObjects((JsonObject) child, builder, level - 1);
}
}
}
}
// ========================================================================
// Utilities - Read and write
// ========================================================================
private static InputStream getInputStream(String filename, boolean isResource) throws FileNotFoundException {
if (isResource) {
ClassLoader loader = JsonSearchUtilities.class.getClassLoader();
return loader.getResourceAsStream(filename);
} else {
return new FileInputStream(new File(filename));
}
}
public static JsonObject readJson(String filename) {
InputStream stream = null;
try {
stream = getInputStream(filename, true);
JsonReader reader = Json.createReader(stream);
return reader.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
public static String prettyPrint(JsonStructure json) {
return jsonFormat(json, JsonGenerator.PRETTY_PRINTING);
}
public static String jsonFormat(JsonStructure json, String... options) {
StringWriter stringWriter = new StringWriter();
Map<String, Boolean> config = new HashMap<String, Boolean>();
if (options != null) {
for (String option : options) {
config.put(option, true);
}
}
JsonWriterFactory writerFactory = Json.createWriterFactory(config);
JsonWriter jsonWriter = writerFactory.createWriter(stringWriter);
jsonWriter.write(json);
jsonWriter.close();
return stringWriter.toString();
}
}
Output
===================
Search by Key
===================
{
"id":"0002",
"Name":"John"
}
===================
Search by Depth
===================
Depth = 0
---------
[
{
"434":{
"Test1":{
"id":"0001",
"Name":"John"
}
},
"435":{
"Test2":{
"id":"0002",
"Name":"John"
}
}
}
]
Depth = 1
---------
[
{
"Test1":{
"id":"0001",
"Name":"John"
}
},
{
"Test2":{
"id":"0002",
"Name":"John"
}
}
]
Depth = 2
---------
[
{
"id":"0001",
"Name":"John"
},
{
"id":"0002",
"Name":"John"
}
]
Depth = 3
---------
[
]
I need to get the value of the key from a dynamic json.
Input-> json Object, String key
Output-> json element(corresponds to the value of the key)
Example
JsonObject Jmsg =
{
"id": "1753_CORE1",
"name": "Gtx cuda Service:1753",
"shortName": "gt-service-1753",
"createdDate": "Mar 31, 2015 4:47:10 PM",
"config": {
"oauthSecret": [
{
"id": 45,
"config123": {
"oauthSecret": "P8n2x5Hsst0nFRRB0A",
"status": "CREATED"
},
"SERVER132": "1000"
},
{
"id": 46,
"config123": {
"oauthSecret": "P8n2x5Htss0nFRRB0A"
},
"SERVER132": "1000"
}
],
"oauthKey": "154284-service-1753",
"SERVER": "1000"
},
"features": [
9004,
9005
]
}
and String key = "status";
then
JsonElement Jvalue = jsonGetValueformKey(Jmsg,key);
should return 'CREATED' in JsonElement or string type.
if String key = "features";
then
JsonElement Jvalue = jsonGetValueformKey(Jmsg,key);
should return [9004,9005] in JsonElement or jsonArray type.
if key not found then return null
JsonObject Jmsg can be anything
please try this
package json;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
public class MyApp {
static List<String> list = new ArrayList<String>();
public static void main(String[] args) {
String key = "oauthSecret";
String json2 = "{\"config\": {\"oauthSecret\": [{\"id\": 45,\"config123\": {\"oauthSecret\": \"P8n2x5Ht0nFRRB0A\",\"status\": \"CREATED\"},\"SERVER132\": \"1000\"},{\"id\": 46,\"config123\": {\"oauthSecret\": \"wP8n2x5Ht0nFRRB0A\",\"status\": \"CREATED\"},\"SERVER132\": \"1000\"}],\"oauthKey\": \"newtest\",\"SERVER\": \"1000\"},\"features\": [ 9004, 9005] ,\"d\":\"dd\"}";
System.out.println("JSON: " + json2);
JsonParser p = new JsonParser();
check(key, p.parse(json2));
System.out.println("list size: " + list.size());
System.out.println(list);
}
private static void check(String key, JsonElement jsonElement) {
if (jsonElement.isJsonArray()) {
for (JsonElement jsonElement1 : jsonElement.getAsJsonArray()) {
check(key, jsonElement1);
}
} else {
if (jsonElement.isJsonObject()) {
Set<Map.Entry<String, JsonElement>> entrySet = jsonElement
.getAsJsonObject().entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
String key1 = entry.getKey();
if (key1.equals(key)) {
list.add(entry.getValue().toString());
}
check(key, entry.getValue());
}
} else {
if (jsonElement.toString().equals(key)) {
list.add(jsonElement.toString());
}
}
}
}
}
This is a draft of a recursive approach for that.
Object find(JSONObject jObj, String k) throws JSONException {
Iterator<?> keys = jObj.keys();
while( keys.hasNext() ) {
String key = (String)keys.next();
if (key.equals(k)) {
return jObj.get(key);
}
if ( jObj.get(key) instanceof JSONObject ) {
return find((JSONObject)jObj.get(key), k);
}
if ( jObj.get(key) instanceof JSONArray ) {
JSONArray jar = (JSONArray)jObj.get(key);
for (int i = 0; i < jar.length(); i++) {
JSONObject j = jar.getJSONObject(i);
find(j, k);
}
}
}
You could use something like this :-
public Object checkKey(JSONObject object, String searchedKey) {
boolean exists = object.containsKey(searchedKey);
Object obj = null;
if(exists){
obj = object.get(searchedKey);
}
if(!exists) {
Set<String> keys = object.keySet();
for(String key : keys){
if ( object.get(key) instanceof JSONObject ) {
obj = checkKey((JSONObject)object.get(key), searchedKey);
}
}
}
return obj;
}
This will give you the Object type for a key OR null if key does not exists.
You can modify it & caste the return Object type to any JSONObject, String or JSONArray depending upon your condition by checking its class using getClass().
Note :- This is just a reference but you can edit it according to your needs.
private Object findJsonParam(JSONObject payload, String param) {
Iterator<?> keys = payload.keys();
System.out.println("payload " + payload);
while (keys.hasNext()) {
String key = (String) keys.next();
if (key.equals(param)) {
return payload.get(key);
} else if (payload.get(key) instanceof JSONObject) {
Object val = findJsonParam(payload.getJSONObject(key), param);
if (val != null)
return val;
} else if (payload.get(key) instanceof JSONArray) {
JSONArray jar = payload.getJSONArray(key);
for (Object jsonObj : jar) {
Object val = findJsonParam((JSONObject) jsonObj, param);
if (val != null)
return val;
}
}
}
return null;
}
I had to make some changes in DrB awnser, it worked for me this way. Because on the first nested json it returned without checking the value, so if the key wasn't in the first one, then it couldn't find it.
public Object find(JSONObject jObj, String k) throws JSONException {
Iterator<?> keys = jObj.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
if (key.equals(k)) {
return jObj.get(key);
}
if (jObj.get(key) instanceof JSONObject) {
Object probableKeyValue = find((JSONObject) jObj.get(key), k);
if(probableKeyValue != null){
return probableKeyValue;
}
}
if (jObj.get(key) instanceof JSONArray) {
JSONArray jar = (JSONArray) jObj.get(key);
for (int i = 0; i < jar.length(); i++) {
JSONObject j = jar.getJSONObject(i);
find(j, k);
}
}
}
return null;
}
I want to extract JSON structure (only keyNames structure) by preserving the hierarchy (parent child relationship); I don't want values from the JSON yet.
I am new to Java and have been tying to achieve this using Jackson , but with no success.
Any direction on this will be much appreciated.
I created a static inner class for you by using JSONObject (http://www.json.org/javadoc/org/json/JSONObject.html)
public static class KeyNode {
private String name;
private ArrayList<KeyNode> children;
public KeyNode(String name) {
this.name = name;
this.children = new ArrayList<KeyNode>();
}
public void addChild(KeyNode child) {
this.children.add(child);
}
public static void parseJsonToKeys(KeyNode node, JSONObject json) throws JSONException {
Iterator<?> keys = json.keys();
while (keys.hasNext()) {
String name = (String) keys.next();
KeyNode child = new KeyNode(name);
node.addChild(child);
if (json.optJSONObject(name) != null) {
parseJsonToKeys(child, json.getJSONObject(name));
} else if (json.optJSONArray(name) != null) {
JSONArray array = json.getJSONArray(name);
for (int i = 0; i < array.length(); i++) {
try {
array.getJSONObject(i);
parseJsonToKeys(child, json.getJSONObject(name));
} catch (JSONException e) {
// this is ok
}
}
}
}
}
public static void exampleCodeUsage() {
try {
JSONObject json = new JSONObject("your json");
KeyNode keyHierarchy = new KeyNode("root");
parseJsonToKeys(keyHierarchy, json);
} catch (JSONException e) {
// your json is not formatted correctly
}
}
}
JSONParser parser = parser;
Object obj = parser.parse(new FileReader(FileName.Json));
JSONObject jobj = (JSONObject) obj;
obj.keys()
The method will give you the list of all keys in JSONObject