Remove JSON object with null value in object node tree - java

I have a JSON file from which I need to remove node objects which contain a data value of null. Can this be done? I'm using Jackson.
In the sample JSON below, I need to remove the object where its "v" tag has a null value.
Example:
{
"tags" : [ {
"tagId" : "G1.A_90LT1OUT",
"data" : [ {
"ts" : "2019-03-20T15:27:36",
"v" : "96.2427826",
"q" : "3"
} ]
}, {
"tagId" : "G1.A_90WN1OUT",
"data" : [ {
"ts" : "2019-03-20T15:27:36",
"v" : null,
"q" : "0"
} ]
}, {
"tagId" : "G1.A_90LT1OUT",
"data" : [ {
"ts" : "2019-03-20T15:29:20",
"v" : "96.2427826",
"q" : "3"
} ]
}, {
"tagId" : "G1.A_90WN1OUT",
"data" : [ {
"ts" : "2019-03-20T15:29:20",
"v" : null,
"q" : "0"
} ]
}, {
"tagId" : "G1.A_90LT1OUT",
"data" : [ {
"ts" : "2019-03-20T15:29:37",
"v" : "96.2581177",
"q" : "3"
} ]
}, {
"tagId" : "G1.A_90WN1OUT",
"data" : [ {
"ts" : "2019-03-20T15:29:37",
"v" : null,
"q" : "0"
} ]
} ]
}
I need it to look like this:
{
"tags" : [ {
"tagId" : "G1.A_90LT1OUT",
"data" : [ {
"ts" : "2019-03-20T15:27:36",
"v" : "96.2427826",
"q" : "3"
} ]
}, {
"tagId" : "G1.A_90LT1OUT",
"data" : [ {
"ts" : "2019-03-20T15:29:20",
"v" : "96.2427826",
"q" : "3"
} ]
}, {
"tagId" : "G1.A_90LT1OUT",
"data" : [ {
"ts" : "2019-03-20T15:29:37",
"v" : "96.2581177",
"q" : "3"
} ]
} ]
}
Can this be done? Please show me how. Fairly new to JSON manipulation, I've seen another post that kind of shows how to remove an element from a node, but I think my case is a little different. I've tried chasing down documentation to no avail, maybe looking in the wrong places.
Thank you in advance.

JSONPath
For JSON manipulation and filtering you can also use JsonPath library. It has a great web tool where you can try different filters and options. We can filter all nodes wit not null values using below path:
$.tags[?(#.data[0].v != null)]
Example application which does the same:
import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
import java.io.File;
public class JsonPathApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
JSONArray filtered = JsonPath.parse(jsonFile).read("$.tags[?(#.data[0].v != null)]");
// Create root object
JSONObject root = new JSONObject();
root.appendField("tags", filtered);
// Get JSON
String json = root.toString();
// Write JSON on console or file
System.out.println(json);
}
}
Above code prints:
{"tags":[{"tagId":"G1.A_90LT1OUT","data":[{"ts":"2019-03-20T15:27:36","v":"96.2427826","q":"3"}]},{"tagId":"G1.A_90LT1OUT","data":[{"ts":"2019-03-20T15:29:20","v":"96.2427826","q":"3"}]},{"tagId":"G1.A_90LT1OUT","data":[{"ts":"2019-03-20T15:29:37","v":"96.2581177","q":"3"}]}]}
Jackson
The same with Jackson we can achieve in that way:
Read JSON as tree
Go to tags array
Iterate over array
For each item find v key in 0-index element
In case it is null - remove it
Example implementation:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(jsonFile);
ArrayNode tags = (ArrayNode) root.get("tags");
Iterator<JsonNode> elements = tags.elements();
while (elements.hasNext()) {
JsonNode item = elements.next();
ArrayNode data = (ArrayNode) item.get("data");
JsonNode v = data.get(0).get("v");
if (v.isNull()) {
elements.remove();
}
}
System.out.println(root);
}
}

Related

How to sort json by values in order to see real DIFF

I try to make a DIFF which does not look at order of my JSON values.
I tried to sort my json before diffing it with import com.fasterxml.jackson.databind.ObjectMapper, but neither SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS or MapperFeature.SORT_PROPERTIES_ALPHABETICALLY sort it as I want.
Somebody knows another way to sort my json by alphabetical values (NB_SUP_HET, NB_SUP_SOL, WEI_MAX) ?
import test.common.JsonDiff
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.MapperFeature
import javax.json.Json
import com.fasterxml.jackson.databind.ObjectMapper
String template = """
{"preparation_order_list" : [ {
"net_weight_to_prepare" : 12.33,
"additional_data_value_list" : [ {
"additional_data_item_code" : "NB_SUP_HET",
"additional_data_item_value" : "001821"
}, {
"additional_data_item_code" : "NB_SUP_SOL",
"additional_data_item_value" : "002000"
}, {
"additional_data_item_code" : "WEI_MAX",
"additional_data_item_value" : "000007358"
} ]
}]}
"""
String file_to_compare = """
{"preparation_order_list" : [ {
"net_weight_to_prepare" : 12.33,
"additional_data_value_list" : [ {
"additional_data_item_code" : "WEI_MAX",
"additional_data_item_value" : "000007358"
}, {
"additional_data_item_code" : "NB_SUP_SOL",
"additional_data_item_value" : "002000"
}, {
"additional_data_item_code" : "NB_SUP_HET",
"additional_data_item_value" : "001821"
} ]
}]}
"""
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
String prettyApiJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapper.readTree(file_to_compare));
String prettyTemplateJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapper.readTree(template));
println "------------------------------------------"
println "prettyApiJson :\n$prettyApiJson"
String diff_string = test.common.JsonDiff.GetJsonDiff(prettyApiJson,prettyTemplateJson)
JsonStructure jsonStructInput = Json.createReader(new StringReader(prettyApiJson)).read()
JsonStructure jsonStructTemplate = Json.createReader(new StringReader(prettyTemplateJson)).read()
JsonPatch diff = Json.createDiff(jsonStructTemplate, jsonStructInput)
println diff.toString()
```
I tried another solution wich is to sort JsonSlurper() object by a recursive function.
But it is hard to make it working as this is a complex object which seem composed of LinkedHashMap, ArrayList, LazyMap, ...
Somebody knows how to easily sort it ?
here is my code try...
def sortSubMap(def root, String keyToSort) {
root.each {
KeywordUtil.logInfo(") inspect:"+it.inspect())
KeywordUtil.logInfo("it " + it.getClass())
KeywordUtil.logInfo("it.value " + it.value.getClass())
if (it.key==keyToSort) {
KeywordUtil.logInfo("*** it.key==keyToSort")
//TODO :let's sort elements of this node "keyToSort" and replace in json_obj
} else if ( it.value instanceof groovy.json.internal.LazyMap) {
KeywordUtil.logInfo("on recurse LazyMap")
it.each { it1 -> sortSubMap(it1, keyToSort) }
sortSubMap(it.value, keyToSort)
} else if (it.value instanceof ArrayList) {
KeywordUtil.logInfo("on recurse ArrayList")
KeywordUtil.logInfo("it.value : " + it.value)
sortSubMap(it.value, keyToSort)
}
}
}
def json_input = """
{"items" : [ {
"net_weight_to_prepare" : 12.33,
"additional_data_value_list" : [ {
"additional_data_item_code" : "WEI_MAX",
"additional_data_item_value" : "000007358"
}, {
"additional_data_item_code" : "NB_SUP_SOL",
"additional_data_item_value" : "002000"
}, {
"additional_data_item_code" : "NB_SUP_HET",
"additional_data_item_value" : "001821"
} ]
}]}
"""
def json_obj = new groovy.json.JsonSlurper().parseText(json_input)
println(json_obj.inspect())
sortSubMap(json_obj,"additional_data_value_list"); println(json_obj.inspect())
for information, I finally succeeded to sort my "additional_data_value_list" by "additional_data_item_code" value alphabetically
Here is resulting recursive function with these strange closure functions :) :
import test.common.JsonDiff
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.MapperFeature
import javax.json.Json
import com.fasterxml.jackson.databind.ObjectMapper
import org.apache.commons.lang3.builder.ToStringBuilder
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import groovy.json.JsonBuilder
// inspired from https://stackoverflow.com/questions/39973481/recursively-removing-whitespace-from-json-field-names-in-groovy
def jsonString = """
{"items" : [ {
"net_weight_to_prepare" : 12.33,
"additional_data_value_list" : [ {
"additional_data_item_code" : "WEI_MAX",
"additional_data_item_value" : "000007358"
}, {
"additional_data_item_code" : "NB_SUP_SOL",
"additional_data_item_value" : "002000"
}, {
"additional_data_item_code" : "NB_SUP_HET",
"additional_data_item_value" : "001821"
} ]
}]}
"""
def json = """
{
"leg bone" : false,
"connected to the" : {
"arm bones " : [
{
" fizz" : "buzz",
"well hello" : "there"
}
]
}
}
"""
def sortNodesInTree(def tree, String nodeName ) {
println "tree1 : "+tree
//println "tree1.key : "+tree.key
switch (tree) {
case Map:
return tree.collectEntries { k, v ->
println "k v : $k $v"
if (k==nodeName) {[(k):v.sort { a,b -> a.additional_data_item_code <=> b.additional_data_item_code}]}
else {
[(k):sortNodesInTree(v,nodeName)]
}
}
case Collection:
println "tree2 : "+tree
return tree.collect { e -> sortNodesInTree(e,nodeName) }
default :
return tree
}
}
def tree = new JsonSlurper().parseText(jsonString)
def fixedTree = sortNodesInTree(tree,"additional_data_value_list")
println new JsonBuilder(fixedTree).toString()
console :
println(JsonBuilder(fixedTree).toString())
{"items":[{"net_weight_to_prepare":12.33,"additional_data_value_list":[{"additional_data_item_code":"NB_SUP_HET","additional_data_item_value":"001821"},{"additional_data_item_code":"NB_SUP_SOL","additional_data_item_value":"002000"},{"additional_data_item_code":"WEI_MAX","additional_data_item_value":"000007358"}]}]}

how I can get data from JSONObject with Java?

I have an String called inputJson that contains
{"listPruebas": [
{
"nombrePrueba" : "pruebaA",
"id" : 1,
"tipoPrueba" : "PRUEBABASE1",
"elementoBase" : "tipoA",
"listaMarca": [
{
"elemento": "elemento1 ",
"tipo": "ABC",
"cadena": "SFSG34235WF32"
},
{
"elemento":"elemento2",
"tipo":"DEF",
"cadena":"DJRT64353GSDG"
},
{
"elemento" : "elemento3",
"formato ":"JPG"
}
]},
{
"nombrePrueba" : "pruebaB",
"id" : 2,
"tipoPrueba" : "PRUEBABASE2",
"elementoBase" : "imagenPrueba",
"listaMarca2": [
{
"elemento" : "imagen",
"tipo": "tipo5",
"cadena": "iVBORw0KGgoAAAANSUhEUgAAAgAAAA"
}
]
}
],
"listaBuscar":
[
{
"tipoBusqueda":"busqueda1",
"id" : 1,
"operacion" : "operacion1",
"valor" : "12"
},
{
"tipoBusqueda":"binario",
"id" : 2,
"operacion" : "operacion2",
"valor" : "13"
},
{
"tipoFiltro":"numerico",
"id" : 31,
"operacion" : "MENOR_QUE",
"valor" : "1980",
"intervalo" : 1
}
]
}
and I converted the String to JSONObject of this way
JSONObject object = new JSONObject(inputJson);
and I got this
jsonObject::{"listaBuscar":[{"valor":"12","id":1,"operacion":"operacion1","tipoBusqueda":"busqueda1"},{"valor":"13","id":2,"operacion":"operacion2","tipoBusqueda":"binario"},{"tipoFiltro":"numerico","intervalo":1,"valor":"1980","id":31,"operacion":"MENOR_QUE"}],"listPruebas":[{"listaMarca":[{"tipo":"ABC","elemento":"elemento1","cadena":"SFSG34235WF32"},{"tipo":"DEF","elemento":"elemento2","cadena":"DJRT64353GSDG"},{"elemento":"elemento3","formato":"JPG"}],"elementoBase":"tipoA","tipoPrueba":"PRUEBABASE1","nombrePrueba":"pruebaA","id":1},{"elementoBase":"imagenPrueba","tipoPrueba":"PRUEBABASE2","listaMarca2":[{"tipo":"tipo5","elemento":"imagen","cadena":"iVBORw0KGgoAAAANSUhEUgAAAgAAAA"}],"nombrePrueba":"pruebaB","id":2}]}
and now I need to extract information but I dont know how to do, for example I try this
object.getString("elemento1");
but I got this error
Caused by: org.json.JONException: JSONObject["elemento1"] not found
help me please
You can't get a nest JSON object from the top level. It's like a treemap. You need to convert it into a java object or get it level by level.
check this post, a lot of ways.
You json contains two json arrays, fetch them as -
JSONArray listaBuscArray = jsonObj.getJSONArray("listaBuscar");
JSONArray listPruebasArray = jsonObj.getJSONArray("listPruebas");
Now you can process and use them as -
for(int i=0; i<listaBuscArray.length; i++){
JSONObject obj = listaBuscArray.getJSONObject(i);
.... your logic
}

How to read json file in java [duplicate]

This question already has answers here:
How to parse JSON in Java
(36 answers)
Closed 5 years ago.
I want to read Json file. My Json File has Content as follow
[
{
"arguments" : [
{
"IsEnabled" : "false",
"class" : "UITextField",
"width" : 238,
"parent" : {
"class" : "UIView",
"height" : 101,
"Y" : 192,
"width" : 280,
"X" : 20
},
"name" : "Enter UserName",
"X" : 40,
"isRightOf" : "NA",
"Recording Device" : "NA",
"Y" : 0
},
{
"data" : "Enter UserName",
"type" : "string"
}
],
}
]
I also tried GSON library to read JSON file.but fails . Please help
The JSON you provided is invalid (there is an invalid comma)
[
{
"arguments" : [
{
"IsEnabled" : "false",
"class" : "UITextField",
"width" : 238,
"parent" : {
"class" : "UIView",
"height" : 101,
"Y" : 192,
"width" : 280,
"X" : 20
},
"name" : "Enter UserName",
"X" : 40,
"isRightOf" : "NA",
"Recording Device" : "NA",
"Y" : 0
},
{
"data" : "Enter UserName",
"type" : "string"
}
], <-- this comma makes the json invalid
}
]
Your input json was wrong there is a comma missing as suggested.
Json objects are very hard to parse but if you once get the concept of how to parse the json data it is really easy.
You need to see if the property you are trying to access is a json array or an object. This is the basic rule if you are a beginner.
Here is the code::
OUTOUT IS::
arguments>>>>>>>>> [{"parent":{"width":280,"X":20,"Y":192,"class":"UIView","height":101},"Recording Device":"NA","IsEnabled":"false","width":238,"name":"Enter UserName","X":40,"isRightOf":"NA","Y":0,"class":"UITextField"},{"data":"Enter UserName","type":"string"}]
{"parent":{"width":280,"X":20,"Y":192,"class":"UIView","height":101},"Recording Device":"NA","IsEnabled":"false","width":238,"name":"Enter UserName","X":40,"isRightOf":"NA","Y":0,"class":"UITextField"}
{"data":"Enter UserName","type":"string"}
So, here in the code you can see that I have taken json array sometimes and object sometime, you need to differentiate between them.
import java.io.FileReader;
import java.io.IOException;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
public class test {
public static void main(String[] args) throws IOException, InterruptedException {
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("test.json"));
JSONArray jsonObject = (JSONArray) obj;
JSONObject arr = (JSONObject) jsonObject.get(0);
JSONArray arguments = (JSONArray) arr.get("arguments");
System.out.println("arguments>>>>>>>>> "+arguments);
for(int i = 0 ; i< arguments.size() ;i++){
JSONObject object = (JSONObject) arguments.get(i);
System.out.println(object);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Get value out JSON Object containing JSON arrays

How can I get the value of "distance" out of the following JSON object with java?
{
"destination_addresses" : [ "New York City, New York, Verenigde Staten" ],
"origin_addresses" : [ "Washington D.C., District of Columbia, Verenigde Staten" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "225 mijl",
"value" : 361714
},
"duration" : {
"text" : "3 uur 51 min.",
"value" : 13877
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
I tried:
json.getJSONArray("rows").getJSONObject(0).getJSONObject("distance").toString();
But I always get org.json.JSONException: JSONObject["distance"] not found.
I think you are missing the second array "elements", you find array "row" so get object 0, in object 0 you need to find the "elements" array then take the object 0 again, so you can get the "distance" object.
Try this:
json.getJSONArray("rows").getJSONObject(0).getJSONArray("elements").getJSONObject(0).getJSONObject("distance").toString();
Again, I think. I hope this helped you.
Use java-json.jar
Convert JSON String to object and fetch the element.
You can refer this.
Try this:
package Sample;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class TestMain
{
public static void main(String[] args) throws JSONException
{
String s="{ \"destination_addresses\" : [ \"New York City, New York, Verenigde Staten\" ], \"origin_addresses\" : [ \"Washington D.C., District of Columbia, Verenigde Staten\" ], \"rows\" : [ { \"elements\" : [ { \"distance\" : { \"text\" : \"225 mijl\", \"value\" : 361714 }, \"duration\" : { \"text\" : \"3 uur 51 min.\", \"value\" : 13877 }, \"status\" : \"OK\" } ] } ], \"status\" : \"OK\"} ";
JSONObject jsonObj = new JSONObject(s);
JSONArray array= (JSONArray) jsonObj.get("rows");
JSONObject jsonObj2 =(JSONObject) array.get(0);
JSONArray array2= (JSONArray)jsonObj2.get("elements");
JSONObject jsonObj3 =(JSONObject) array2.get(0);
System.out.println(jsonObj3.get("distance"));
}
}
OUTPUT:
{"text":"225 mijl","value":361714}

How to find a value within a JSONObject/Array Lookup

Below is the JSON feed:
{
"list" : {
"meta" : {
"type" : "resource-list",
"start" : 0,
"count" : 2
},
"resources" : [
{
"resource" : {
"classname" : "Quote",
"fields" : {
"name" : "USD/KRW",
"price" : "1151.295044",
"symbol" : "KRW=X",
"ts" : "1437357550",
"type" : "currency",
"utctime" : "2015-07-20T01:59:10+0000",
"volume" : "0"
}
}
}
,
{
"resource" : {
"classname" : "Quote",
"fields" : {
"name" : "SILVER 1 OZ 999 NY",
"price" : "0.067476",
"symbol" : "XAG=X",
"ts" : "1437169614",
"type" : "currency",
"utctime" : "2015-07-17T21:46:54+0000",
"volume" : "62"
}
}
}
,
{
"resource" : {
"classname" : "Quote",
"fields" : {
"name" : "USD/VND",
"price" : "21815.500000",
"symbol" : "VND=X",
"ts" : "1437357540",
"type" : "currency",
"utctime" : "2015-07-20T01:59:00+0000",
"volume" : "0"
}
}
}
]
}
}
How do I go about finding the "price" of the JSON object who's symbol is ("symbol" : "XAG=X") for example. In this case the answer is ("price" : "0.067476"). I need to perform this lookup programatically since the JSON is rather larger than the one presented here and the only parameter given to me will be the "symbol".
Is this possible? Any detailed help on how to do this would be greatly appreciated.
This is your Json object Format
Try this for getting correct result -
JSONObject list = new JSONObject(content).getJSONObject("list");
JSONArray resources = list.getJSONArray("resources");
for (int j = 0; j < resources.length(); j++) {
JSONObject resource = resources.getJSONObject(j).getJSONObject("resource");
JSONObject fields = resource.getJSONObject("fields");
if(fields.getString("symbol").equals("XAG=X")){
System.out.println("Price of symbol(XAG=X) is"+ fields.getString("price"));
}
}
Assuming content represents the json string
import org.json.JSONArray;
import org.json.JSONObject;
JSONObject list = new JSONObject(content).getJSONObject("list");
JSONArray resources = list.getJSONArray("resources");
for (int j = 0; j < resources.length(); j++) {
JSONObject resource = resources.getJSONObject(j).getJSONObject("resource");
JSONObject fields = resource.getJSONObject("fields");
System.out.println(fields.get("symbol"));
System.out.println(fields.get("price"));
}

Categories

Resources