Find Value for a Key from a Dynamic Json Using Java

Find value for a key from a dynamic json using java

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());
}
}
}
}

}

Dynamic Json Parsing in JAVA And Find the keys and values pairs?

It is uncommon to process a json structure that you do not know anything about. If you do not know what values you are looking for, how is this data ever going to be useful?

In the special cases you do want to go over the whole tree, you will have to use recursion. Because every field (field) can have a simple value ("field": 1), an object ("field": {"b": 1}) or an array ("field": [1, 2, 3]).

The below code shows how you could do this using the Jackson json library

public static void main(String[] args) throws IOException {
File file = new File("data.json");
ObjectMapper mapper = new ObjectMapper();

JsonNode node = mapper.readTree(file);

processNode(node);
}

private static void processNode(JsonNode node) {
if(node.isArray()) {
// if the node is a list of items,
// go through all the items and process them individually
System.out.println("=== Array start ===");
for (final JsonNode objInArray : node) {
System.out.println("--- Array element start ---");
// process the item in the array
processNode(objInArray);
System.out.println("--- Array element end ---");
}
System.out.println("=== Array end ===");
} else if(node.isContainerNode()) {
// if the node is an object,
// go through all fields within the object
System.out.println("/// Object start ///");
Iterator<Map.Entry<String, JsonNode>> it = node.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> field = it.next();
System.out.println("key: " + field.getKey());
//process every field in the array
processNode(field.getValue());
}
System.out.println("/// Object end ///");
} else {
// if node is a simple value (like string or int) so let's print it
System.out.println("value: " + node);
}
}

The example json you provided gives the following output:

=== Array start ===
--- Array element start ---
/// Object start ///
key: id
value: 1
key: name
value: "Leanne Graham"
key: username
value: "Bret"
key: email
value: "Sincere@april.biz"
key: address
/// Object start ///
key: street
value: " Light"
key: suite
value: "Apt. 556"
key: city
value: "Gwugh"
key: zipcode
value: "93874"
key: geo
/// Object start ///
key: lat
value: "-37.319"
key: lng
value: "81.146"
/// Object end ///
/// Object end ///
key: phone
value: "8031 x56442"
key: website
value: "hilded.org"
key: company
/// Object start ///
key: name
value: "Romra-Crona"
key: catchPhrase
value: " client-server neural-net"
key: bs
value: "harness markets"
/// Object end ///
/// Object end ///
--- Array element end ---
=== Array end ===

Process finished with exit code 0

Get dynamic Key and value from json file

Couple of things, first your json is malformed. Remove the comma at the end of the following line in both elements.

"update_date": "2018-08-28T12:32:55.640Z",

Second, the object is an array as you see in the error message. So, change your code to use JSONArray instead of JSONObject,

JSONArray jsonArray = (JSONArray) obj;

From there, you have to modify your print function to take JSONArray and use additional for loop to traverse through the loop. Something like this,

for (Object json : jsonArray) {
printJSONOBject((JSONObject) json)
}

private void printJSONOBject(JSONObject jsonObject) {
for (Object keyObj : jsonObject.keySet()) {
String key = (String) keyObj;
Object valObj = jsonObject.get(key);
if (valObj instanceof JSONObject) {
printJSONOBject((JSONObject) valObj);
} else {
System.out.println(key + " : " + valObj);
}
}
}

How to parse a dynamic JSON key in a Nested JSON result?

Use JSONObject keys() to get the key and then iterate each key to get to the dynamic value.

Roughly the code will look like:


// searchResult refers to the current element in the array "search_result" but whats searchResult?
JSONObject questionMark = searchResult.getJSONObject("question_mark");
Iterator keys = questionMark.keys();

while(keys.hasNext()) {
// loop to get the dynamic key
String currentDynamicKey = (String)keys.next();

// get the value of the dynamic key
JSONObject currentDynamicValue = questionMark.getJSONObject(currentDynamicKey);

// do something here with the value...
}

How to replace a value of the given key path in dynamic json object using java

Through below code able to replace or remove the given item.

public JSONObject updateOrRemoveJsonProperty(Object js1, String keys, Object valueNew, ConfigData.JsonBuildType payloadEnum, String targetKey){
try {
List<String> keyMain = new LinkedList<String>(Arrays.asList(keys.split("\\.")));

for (int i = 0; i < keyMain.size(); i++) {
if(js1 instanceof JSONObject || js1 instanceof JSONArray){
if(keyMain.size() >1 && i+1 < keyMain.size()) {
String tmpKey= "";
String stringArray ="";
try {
tmpKey = keyMain.get(i);
keyMain.remove(i);
stringArray = StringUtils.join(keyMain, ".");
keyMain.clear();
updateOrRemoveJsonProperty(((JSONObject) js1).get(tmpKey), stringArray, valueNew, payloadEnum, targetKey);
}catch (JSONException js){
if(!tmpKey.isEmpty() && tmpKey.matches(KeyMapper.KEYLSTREGX)){
String[] tmp = tmpKey.replaceFirst(KeyMapper.KEYLSTREGX, "$1, $2").split(",");
try {
updateOrRemoveJsonProperty((JSONArray)(((JSONArray)((JSONObject) js1).get(tmp[0])).get(Integer.parseInt(tmp[1].trim()))), stringArray, valueNew, payloadEnum, targetKey);
}catch (ClassCastException ex){
updateOrRemoveJsonProperty((JSONObject)(((JSONArray)((JSONObject) js1).get(tmp[0])).get(Integer.parseInt(tmp[1].trim()))), stringArray, valueNew, payloadEnum, targetKey);
}
}
}
} else {
if((keyMain.get(i)).length() > 2 && keyMain.get(i).matches(KeyMapper.KEYLSTREGX)){
String[] tmp = keyMain.get(i).replaceFirst(KeyMapper.KEYLSTREGX, "$1, $2").split(",");
if(targetKey != "" && tmp[0].trim().equals(targetKey) && !payloadEnum.equals(ConfigData.JsonBuildType.REMOVE)) {
((JSONObject) js1).put(tmp[0], valueNew);
} else if (targetKey != "" && tmp[0].trim().equals(targetKey) && payloadEnum.equals(ConfigData.JsonBuildType.REMOVE)){
((JSONObject) js1).remove(tmp[0]);
}

}
if(targetKey != "" && keyMain.get(i).equals(targetKey) && !payloadEnum.equals(ConfigData.JsonBuildType.REMOVE)) {
((JSONObject) js1).put(keyMain.get(i), valueNew);
} else if (targetKey != "" && keyMain.get(i).equals(targetKey) && payloadEnum.equals(ConfigData.JsonBuildType.REMOVE)){
((JSONObject) js1).remove(keyMain.get(i));
}
}
}
}
}catch (JSONException ex){

}

return (JSONObject) js1;
}

How to get dynamically changed Key's value in Json String using java

So your problem is the key 8080/tcp is not fixed and it may change. when this situation you can try like this to get the value of the Dynamic key.

Set<Map.Entry<String, JsonElement>> entrySet = ntw_Ports_obj
.entrySet();

for (Map.Entry<String, JsonElement> entry : entrySet) {
String key = entry.getKey();
JsonArray jArray = (JsonArray) ntw_Ports_obj.get(key);
System.out.println(jArray);
}

Edit:

Object keyObjects = new Gson().fromJson(ntw_Ports_obj, Object.class);
List keys = new ArrayList();

/** for the given json there is a one json object within the 'Ports' so the 'keyObjects' will be the 'Map'**/
if (keyObjects instanceof Map) {
Map map = (Map) keyObjects;
keys.addAll(map.keySet());
/**
* keys is a List it may contain more than 1 value, but for the given
* json it will contain only one value
**/
String key = (String) keys.get(0);
JsonArray jArray = (JsonArray) ntw_Ports_obj.get(key);
System.out.println(jArray);
}

How to Parse JSON with dynamic Keyname?

It looks like each item in the array only has 1 key/value pair which holds another json object which then has several.

If this is the case, then you could probably do something like this:

for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonObject = jsonArray.getJSONObject(i);

JSONObject innerObject = jsonObject.getJSONObject(jsonObject.keys().next().toString());

/// do something with innerObject which holds aa, bb, cc
}

You simply grab the 1st key in the wrapping object, and use that to grab the inner json object.

Parse JSON with dynamic key object inside dynamic key object with Gson

Your models cannot map your JSON just because Gson default configuration clearly gets them unmatched.

You can have two "default" ways:

static

... since you didn't really mention why your JSON is considered dynamic:

final class XYZ {

final ABC x = null;
final ABC y = null;
final ABC z = null;

}
final class ABC {

final OneTwo a = null;
final OneTwo b = null;

}
final class OneTwo {

@SerializedName("1")
final List<Integer> one = null;

@SerializedName("2")
final List<Integer> two = null;

}

Example:

try ( final Reader reader = getPackageResourceReader(Q43695739.class, "dynamic.json") ) {
final XYZ xyz = gson.fromJson(reader, XYZ.class);
System.out.println(xyz.x.b.two);
}

dynamic (by deserialization)

... assuming your keys are dynamic, but the structure remains the same:

private static final Type stringToStringToStringToIntegerListType = new TypeToken<Map<String, Map<String, Map<String, List<Integer>>>>>() {
}.getType();
try ( final Reader reader = getPackageResourceReader(Q43695739.class, "dynamic.json") ) {
final Map<String, Map<String, Map<String, List<Integer>>>> m = gson.fromJson(reader, stringToStringToStringToIntegerListType);
System.out.println(m.get("x").get("b").get("2"));
}

dynamic (by JSON trees)

Another true dynamic approach that may be helpful for some scenarios. Also note that JSONObject is not in the Gson realm: you probably might have imported this one from the org.json package. Gson uses camel-cased names like JsonElement, JsonObject, etc.

try ( final Reader reader = getPackageResourceReader(Q43695739.class, "dynamic.json") ) {
final JsonElement jsonElement = gson.fromJson(reader, JsonElement.class)
.getAsJsonObject()
.getAsJsonObject("x")
.getAsJsonObject("b")
.getAsJsonArray("2");
System.out.println(jsonElement);
}

The first and the second examples produce java.util.List instances

[1, 2, 3, 4]

The third example returns a JsonArray instance with a slightly different toString implementation:

[1,2,3,4]



Related Topics



Leave a reply



Submit