Here is my Json File:
{
\"models\":{},
\"path\":[
{
\"path\":\"/web-profiles\",
\"operations\":[
{
In Scala with org.json
library, can be easily converted to Java (although a bit more verbose). Recursively removes null
s and empty objects/arrays:
import org.json.{ JSONArray, JSONObject }
object JsonCleaner {
def clean(json: JSONObject): Boolean = {
val i = json.keys()
while (i.hasNext) clean(i, json.get(i.next()))
json.length == 0
}
def clean(json: JSONArray): Boolean = {
val i = json.iterator()
while (i.hasNext) clean(i, i.next())
json.length == 0
}
private def clean(i: java.util.Iterator[_], v: Any) {
v match {
case o: JSONObject =>
if (clean(o)) i.remove()
case a: JSONArray =>
if (clean(a)) i.remove()
case JSONObject.NULL | "" =>
i.remove()
case _ =>
}
}
}
Don't know about any build-in functions but you could try this
public boolean cleanJSON(Object arg) throws JSONException{
boolean valueExist = false;
if(arg instanceof String){
String str= (String)arg;
if(!str.equals("")) valueExist = true;
}else if(arg instanceof JSONObject){
JSONObject obj = (JSONObject)arg;
Iterator<String> iter = obj.keys();
ArrayList<String> fields = new ArrayList<>();
while(iter.hasNext()) fields.add(iter.next());
for(String field:fields){
Object value = obj.get(field);
if(cleanJSON(value)) valueExist = true;
else obj.remove(field);
}
}else if(arg instanceof JSONArray){
JSONArray arr = (JSONArray)arg;
for(int i=0;i<arr.length();i++){
if(cleanJSON(arr.get(i))) valueExist = true;
else{
arr.remove(i);
i--;
}
}
}
return valueExist;
}
That would clean your json object from empty field(it work recursively). So if the JSON looks like this:
"operations":[
{
"nickname":"",
"type":"",
"responseMessages":[]
}]
field "operations" will also removed.
note : JSONArray.remove only work for API 19 above
This should do the trick::
Iterator<String> keys = jsonObject.keys();
while(keys.hasNext()) {
String key = keys.next();
boolean propertyValuePresent = jsonObject.get(key) != null
&& jsonObject.get(key)!="null"
&& !jsonObject.get(key).toString().isEmpty();
if(propertyValuePresent){
jsonObject.remove(key);
}
}
Regex solution
You could use REGEX to remove any line from your data that conatins a "",[],or {} before you parse it with the JSONParser.
The regex for something like this would look like. Keep in mind that you may have to adjust the new line character depending on your OS
[^\n]*(\"(\n)*\"|\[(\n)*\]|\{(\n)*\})[^\n]*
To account for an instance where the JSON data is as follows
{
"models":{},
"path":[
{
"path":"/web-profiles",
"operations":[
{
"nickname":"",
"type":"",
"responseMessages":[]
}
]
}
],
"produces":[]
}
The first time you run that replaceAll it will result with
{
"path":[
{
"path":"/web-profiles",
"operations":[
{
}
]
}
],
}
Now we an empty JSONObject inside of the "operations" JSONArray. So this replaceAll function needs to be called again untill the JSON String doesn't have any changes from it's previous state.
Keep in mind that if you use functions like readLine() during data input it can remove the newline character which will make this method not work. So solve this replace your read line with this.
json += in.readLine() + '\n';
Here is a quick program I wrote that does the actual removal of empty json objects from the original String.
public static void main(String[] args){
// String from above example with newline characters intact
String json = "{\n\"models\":{},\n\"path\":[\n{\n\"path\":\"/web-profiles\",\n\"operations\":[\n{\n\"nickname\":\"\",\n\"type\":\"\",\n\"responseMessages\":[]\n}\n]\n}\n],\n\"produces\":[]\n}";
// Value from the last iteration of the while loop
String last = "";
// If there was no change from the last replaceAll call stop
while( !last.equals(json) ){
last = json;
// Same regex as above just escaped to work in a Java String
json = json.replaceAll("[^\\n]*(\\{(\\n)*\\}|\\\"(\\n)*\\\"|\\[(\\n)*\\])[^\\n]*\\n","");
}
System.out.println(json);
}
First, you should deserialize json
to a Map<String, Object>
.
Second, loop the map entry to find out what key has null value or what key has value is instance of ArrayList
but empty and remove from the Map
.
Last, serialize the Map
to json
.
Try this code:
String json = "{'a': 'apple', 'b': 'ball', 'c': 'cat', 'd': null, 'e': []}";
Type type = new TypeToken<Map<String, Object>>() {}.getType();
Map<String, Object> data = new Gson().fromJson(json, type);
for (Iterator<Map.Entry<String, Object>> it = data.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Object> entry = it.next();
if (entry.getValue() == null) {
it.remove();
} else if (entry.getValue() instanceof ArrayList) {
if (((ArrayList<?>) entry.getValue()).isEmpty()) {
it.remove();
}
}
}
json = new GsonBuilder().setPrettyPrinting().create().toJson(data);
System.out.println(json);
If you use javax.api API:
public static JsonArray removeNull(JsonArray array) {
JsonArrayBuilder builder = Json.createArrayBuilder();
int i = 0;
for (Iterator<JsonValue> it = array.iterator(); it.hasNext(); ++i) {
JsonValue value = it.next();
switch (value.getValueType()) {
case ARRAY:
JsonArray a = removeNull(array.getJsonArray(i));
if (!a.isEmpty())
builder.add(a);
break;
case OBJECT:
JsonObject object = removeNull(array.getJsonObject(i));
if (!object.isEmpty())
builder.add(object);
break;
case STRING:
String s = array.getString(i);
if (s != null && !s.isEmpty())
builder.add(s);
break;
case NUMBER:
builder.add(array.getJsonNumber(i));
break;
case TRUE:
case FALSE:
builder.add(array.getBoolean(i));
break;
case NULL:
break;
}
}
return builder.build();
}
public static JsonObject removeNull(JsonObject obj) {
JsonObjectBuilder builder = Json.createObjectBuilder();
for (Iterator<Entry<String, JsonValue>> it = obj.entrySet().iterator(); it.hasNext();) {
Entry<String, JsonValue> e = it.next();
String key = e.getKey();
JsonValue value = e.getValue();
switch (value.getValueType()) {
case ARRAY:
JsonArray array = removeNull(obj.getJsonArray(key));
if (!array.isEmpty())
builder.add(key, array);
break;
case OBJECT:
JsonObject object = removeNull(obj.getJsonObject(key));
if (!object.isEmpty())
builder.add(key, object);
break;
case STRING:
String s = obj.getString(key);
if (s != null && !s.isEmpty())
builder.add(key, s);
break;
case NUMBER:
builder.add(key, obj.getJsonNumber(key));
break;
case TRUE:
case FALSE:
builder.add(key, obj.getBoolean(key));
break;
case NULL:
break;
}
}
return builder.build();
}
@Test
public void testRemoveNullJsonObject() {
String str = ""
+ "{"
+ " \"models\":{},"
+ " \"path\":["
+ " {"
+ " \"path\":\"/web-profiles\","
+ " \"operations\":["
+ " {"
+ " \"nickname\":\"CreateAWebExperienceProfile\","
+ " \"type\":\"\","
+ " \"responseMessages\":[]"
+ " }"
+ " ]"
+ " }"
+ " ],"
+ " \"produces\":[]"
+ "}";
JsonObject json = Json.createReader(new StringReader(str)).readObject();
System.out.println(json);
JsonObject removed = removeNull(json);
System.out.println(removed);
// -> {"path":[{"path":"/web-profiles","operations":[{"nickname":"CreateAWebExperienceProfile"}]}]}
}