I am finding a solution for get each single key value of a JSONObject dynamicaly.
I have a JSON file like this:
{
"RESPONSE":{
"A":"test",
"B":{
"C":"0",
"D":"1"
},
"E":{
"F":"2",
"G":"3"
}
}
}
I wish to create a Hashmap that contains the key and the value of the objects, like this example:
legend:
key = value
"A" = "test"
"B" = "{"C":"0", "D":"1"}"
"B.C" = "0"
"B.D" = "1"
"E" = "{"F":"2","G":"3"}"
"E.F" = "2"
"E.G" = "3"
I have tried writing this code:
private static HashMap<String, Object> createJsonObjectsHashMapOfConfigFile(String jsonFilePath,
String JsonObjectToIterate) throws Exception {
HashMap<String, Object> jHashMap = new HashMap<>();
JSONObject jsonConfigFile = SimulatorUtil.readJsonFromFile(jsonFilePath); // Returns the Json file
JSONObject jsonConfigObj = jsonConfigFile.getJSONObject(JsonObjectToIterate); // JsonObjectToIterate -->
// "RESPONSE"
Iterator<?> configIter = jsonConfigObj.keys();
String currentDynamicKey = "";
while (configIter.hasNext()) {
currentDynamicKey = (String) configIter.next();
Object currentDynamicValue = jsonConfigObj.get(currentDynamicKey);
jHashMap.put(currentDynamicKey, currentDynamicValue);
logger.info(" ---> " + jHashMap.toString());
}
return jHashMap;
}
but it get only the first level key ("A", "B", "E").
I must use org.json.
Can anyone help me?
Thanks,
Luca
Related
I am struggling with a specific problem, that I cannot think of correctly. The following is the problem
I have a map with key value like the following, i just used strings here
String key = "activate.message.success"
String value = "success"
String key1 = "activate.title"
String value1 = "Good Title"
String key2 = "activate.message.error"
String value2 = "error"
String key3 = "activate.message.short.poll"
String value3 = "This is short poll"
I need to build a json like the following
{
"activate":{
"message":{
"success":"success",
"error":"error",
"short":{
"poll":"This is short poll"
}
},
"title":"Good Title"
}
}
I could not think of a proper solution for this use case and struggling for 3 hours. I thought of using recursion, but i dont how exactly i could do. Please help with this. I am using java for this, I should use generic JSONObject to solve as there is not POJO mappings. So far I have just splitted the strings using separtor and stored in an another map like the following
public Map<String, Object> getJsonObjectFromKeyValueMap(Map<String, String> stringValueMap,
Map<String, Object> stringObjectMap) {
for (Entry entry : stringValueMap.entrySet()) {
String[] keyValueArrayString = entry.getKey().toString().split("\\.");
int sizeOfMap = keyValueArrayString.length;
int i = 0;
String concatString = "";
for (String processKey : keyValueArrayString) {
if (i < sizeOfMap - 1) {
concatString += processKey + ".";
stringObjectMap.put(concatString, (Object) new JSONObject());
} else {
concatString += processKey;
stringObjectMap.put(concatString, entry.getValue());
concatString = "";
}
i++;
}
}
return stringObjectMap;
}
First, let's update your data into a proper map :
Map<String, String> data = new HashMap<>();
data.put("activate.message.success", "success");
data.put("activate.title", "Good Title");
data.put("activate.message.error", "error");
data.put("activate.message.short.poll", "This is short poll");
Then, your logic is pretty close, for each node but the last, you create a new JSONObject, for the last, you insert the value.
If you try to build a JSONObject instead of the map directly, you would get a pretty good result already, well somewhat of a result.
The following will iterate a Map<String, String> of data.
For each entry, we split the key to getting the nodes.
Then, we just need to move in the json, if a node doesn't exist, we create it.
Then, for the last value, create the value.
public static JSONObject build(Map<String, String> data) {
JSONObject json = new JSONObject();
//Iterate the map entries
for (Entry<String, String> e : data.entrySet()) {
String[] keys = e.getKey().split("\\.");
// start from the root
JSONObject current = json;
for (int i = 0; i < keys.length; ++i) {
String key = keys[i];
//Search for the current node
try {
//If it exist, do nothing
current = current.getJSONObject(key);
} //If it does not exist
catch (JSONException ex) {
//Is it the last node, create the value
if (i == keys.length - 1) {
current.put(key, e.getValue());
} //Not the last node, create a new JSONObject
else {
JSONObject tmp = new JSONObject();
current.put(key, tmp);
current = tmp; //Always replace current with the last node to go deeped each iteration
}
}
}
}
return json;
}
And the example :
public static void main(String[] args) {
Map<String, String> data = new HashMap<>();
data.put("activate.message.success", "success");
data.put("activate.title", "Good Title");
data.put("activate.message.error", "error");
data.put("activate.message.short.poll", "This is short poll");
JSONObject json = build(data);
System.out.println(json.toString(4));
}
Ouptut:
{"activate": {
"message": {
"success": "success",
"short": {"poll": "This is short poll"},
"error": "error"
},
"title": "Good Title"
}}
Note : I used an exception to check for the existance of the key, if the map is huge, this could have some impact so you can simply use :
if(current.isNull(key)){
if (i == keys.length - 1) {
current.put(key, e.getValue());
} else {
JSONObject tmp = new JSONObject();
current.put(key, tmp);
current = tmp;
}
} else {
current = current.getJSONObject(key);
}
This was created using org.json/json
I have a Json String representing a object which further has another nested objects. Also, I have a list of keys which I need to remove from this Json String. These keys can be at any nested level of object inside this string. Finally I need to compare this edited Json string to another string and output the differences. I need to remove those key-value pairs from first Json string because I need to ignore those keys during comparison. Currently, I am converting the Json String to LinkedTreeMap provided by Gson API and then doing Map.difference() to compare. Please suggest a solution to this.
I did it by traversing recursively inside the Nested LinkedTreeMap till I find the field and remove it if it exists. The full path of Key needs to be provide to get the exact key-value location inside the Object (like "objects.desc" in the below Json Sample to remove desc from the Json String)
Json Sample:
{
"message": "MSG",
"code": "COD001",
"objects": [
{
"resource": "Student",
"field": "StudentId",
"desc": "Student Description"
}
]
}
Code Sample:
public MapDifference<String, Object> getMapDifference(String jsonString1, String jsonString2) {
MapDifference<String, Object> mapDifference = null;
Gson gson = new Gson();
Type mapType = new TypeToken<Map<String, Object>>() {
}.getType();
Map<String, Object> firstMap = gson.fromJson(jsonString1, mapType);
Map<String, Object> secondMap = gson.fromJson(jsonString2, mapType);
firstMap = CollectionUtils.isEmpty(firstMap) ? new HashMap<>() : firstMap;
secondMap = CollectionUtils.isEmpty(secondMap) ? new HashMap<>() : secondMap;
//This contains the List of keys that is required to be filtered out from Json Strings before comparision like {"message", "objects.desc"}
List<String> firstIgnoreList = getIgnoreList1();
List<String> secondIgnoreList = getIgnoreList2();
filterKeys(firstMap, firstIgnoreList);
filterKeys(secondMap, secondIgnoreList);
mapDifference = Maps.difference(firstMap, secondMap);
return mapDifference;
}
private void filterKeys(Map<String, Object> keyMap, List<String> ignoreList) {
if (!(CollectionUtils.isEmpty(keyMap) || CollectionUtils.isEmpty(ignoreList))) {
ignoreList.stream().parallel().forEach(key -> recursiveRemove(keyMap, key));
}
}
private static void recursiveRemove(Map<String, Object> keyMap, String key) {
List<String> path = Arrays.asList(StringUtils.split(key.trim(), "."));
int size = path.size();
int index = 0;
List<LinkedTreeMap> treeMapList = new ArrayList<LinkedTreeMap>();
treeMapList.add((LinkedTreeMap) keyMap);
while (index != size - 1) {
int i = index++;
List<LinkedTreeMap> treeMapListTemp = new ArrayList<LinkedTreeMap>();
treeMapList.stream().parallel().forEach(treeMap -> {
Object obj = treeMap.get(path.get(i));
if (obj instanceof List) {
treeMapListTemp.addAll((List<LinkedTreeMap>) obj);
} else if (obj instanceof LinkedTreeMap) {
treeMapListTemp.add((LinkedTreeMap) obj);
}
});
treeMapList = treeMapListTemp;
}
treeMapList.stream().parallel().forEach(treeMap -> treeMap.remove(path.get(size - 1)));
}
I have been trying to get the key and value of my JSONObject. I have no idea why this isn't working, because String key is clearly a string?
My code:
JSONObject obj = new JSONObject(historie2.getData());
Iterator<?> keys = obj.keys();
while(keys.hasNext()) {
String key = (String)keys.next();
String value = obj.getString(key); //This is where the error comes
}
The JSONObject:
{
"relatie_website": ["www.apple.com"],
"relatie_kvknummer": ["NL3234234"],
"relatie_naam": ["Apple international inc."],
"relatie_d400code": [null],
"relatie_zoeknaam": ["APPLE INC"],
"relatie_debiteurnummer": ["3523523"],
"relatie_btwnummer": ["332342"]
}
This is the error I have been getting:
org.json.JSONException: JSONObject["relatie_website"] not a string.
You should change your object to be sth like that :
{
"relatie_website": "www.apple.com",
"relatie_kvknummer": "NL3234234",
"relatie_naam": "Apple international inc.",
"relatie_d400code": null,
"relatie_zoeknaam": "APPLE INC",
"relatie_debiteurnummer": "3523523",
"relatie_btwnummer": "332342"
}
Because the problem is that your values are an array and not a string.
But if you need te keep your values in an array you can change your code to support the arrays :
JSONObject obj = new JSONObject(historie2.getData());
Iterator<?> keys = obj.keys();
while(keys.hasNext()) {
String key = (String)keys.next();
JSONArray value = obj.getJSONArray(key);
}
And you will have a JsonArray that you can manipulate as you want by doing sth like that :
for (int i = 0; i < value.length(); i++) {
String val = value.getString(i).toString();
logger.info("val : " + val);
}
I've got my php code:
<?php
require('conn.php');
$json = array();
$newquery = "SELECT * FROM absent";
$newresult = mysqli_query($conn, $newquery);
$jsonData = array();
while ($array = mysqli_fetch_array($newresult)) {
array_push($jsonData,array(
"username"=>$array['username'],
"date"=>$array['date']
));
}
echo json_encode(array("result"=>$jsonData), true);
mysqli_close($conn);
?>
and it returned :
{"result":[{"username":"verarmond","date":"2016-11-17"},{"username":"henk","date":"2016-11-15"}]}
How can i get only usernames and only dates in android ??
Thanks and regard.
HashMap is a data structure based on (key, value) pairs.
So, when you do this:
map.put("iOS", "100");
map.put("Android", "101");
You put the value "100" at "iOS" key, and value "101" at "Android" key.
If you want to access this values, you simply use the "map" object and get the value by the key, like this:
String val1 = map.get("iOS"); //this returns "100"
String val2 = map.get("Android"); // this returns "101"
To get all the entries from a map:
ArrayList<String> values = new ArrayList<>();
for (
Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String Value = entry.getValue();
values.add(Value); //this will add all the values in the hashmap into `values` arraylist
}
It is very easy, you can do it by translating your JSON result to a JSON object with:
JSONObject jsonResult = new JSONObject(jsonString);
Then take your JSON array named result:
JSONArray jsonResultArray = new JSONArray(jsonResult.getJSONArray("result"));
Now you can iterate through your JSON Array to get the required elements:
for(JSONObject jsonObject:jsonResultArray) {
Log.d("TAG", "User: " + jsonObject.getString("username"));
Log.d("TAG", "Date: " + jsonObject.getString("date"));
}
You should know that every { means a JSONObject and the [ means a JSONArray, wit that you should have enough to go.
I wrote the code on the fly and can't check it now, maybe there are some typo or error.
I am getting this string from a service. I want a map or json out of this. It should look like this.
Map output
Total time taken:226006
nodea:10615
nodez:5308'
String timingTrace = "Total time taken:226006.,"
+ "time spent in nodes:{\"nodea\":{\"timeTaken\":10615},\"nodez\":{\"timeTaken\":5308}}\"";
What I have tried so for is the below code. Can I do something better? Any library that can easily convert the above string to map.
if (timingTrace != null) {
arrayofTimeStamp = StringUtils.splitByWholeSeparator(StringUtils.remove(timingTrace, " "), ".,");
}
String[] totaltime = StringUtils.split(arrayofTimeStamp[0], ":")
Map<String,Object> timestamps = new HashMap<String, Object>();
timestamp.put(totaltime[0], totaltime[1]);
String[] nodetimestamp = StringUtils.splitByWholeSeparator(arrayofTimeStamp[1], "time spent in nodes:");
getMapped(nodetimestamp[1]);
public void getMapped(String json) throws JSONException, ParseException {
JSONObject obj = new JSONObject(json);
Iterator<String> keys = obj.keys();
while (keys.hasNext()) {
String key = keys.next();
String timetaken = JsonPath.read(json, "$." + key + ".timeTaken");
timestamp.put(key, timetaken);
}
}
You are using timestamp Map<> object in function getMapped(String json) that give you error because you haven't passed it you declare in function.
To get output you have mention change write below code instead of function getMapped(String json) :
JSONObject obj = new JSONObject(nodetimestamp[1]);
Iterator<String> keys = obj.keys();
while (keys.hasNext())
{
String key = keys.next();
String timetakenStr = obj.getString(key);
JSONObject child = new JSONObject(timetakenStr);
timestamps.put(key, child.getString("timeTaken"));
}
Using above code your Map<> will contain same what you mention.
OutPut :
{nodea=10615, Total time taken=226006, nodez=5308}