JSONObject removes pairs of empty values

Here is my Json file:

{ "models":{}, "path":[ { "path":"/web-profiles", "operations":[ { "type":"", "responseMessages":[] } ] } ], "produces":[] } 

If the key values ​​are empty (including [], "", {}). How to remove these pairs from a json file.

  • I tried using the built-in JSONObject functions to remove unnecessary pairs. But that did not work.
  • I tried using the string method to process it line by line. I have too many cases, I can not cover all these cases in my code. (for example, the β€œoperations” subkey, when you want to delete all empty values, this pair of values ​​(operations) should also be deleted.) Any ideas?
+5
source share
5 answers

First, you must deserialize json to Map<String, Object> . Second, loop the map entry to find out which key has a null value or which key has a value, is an ArrayList instance, but empty and removed from Map . Finally serialize 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); 
+1
source

If you use the 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"}]}]} } 
+1
source

Regression solution

You can use REGEX to remove any line from your data that binds "", [] or {} before you parse it with JSONParser.

A regular expression for something like this will look like. Keep in mind that you may have to configure a new line symbol depending on your OS.

 [^\n]*(\"(\n)*\"|\[(\n)*\]|\{(\n)*\})[^\n]* 

To account for the instance in which the JSON data looks like this

 { "models":{}, "path":[ { "path":"/web-profiles", "operations":[ { "nickname":"", "type":"", "responseMessages":[] } ] } ], "produces":[] } 

The first time you run replaceAll, this will result in

 { "path":[ { "path":"/web-profiles", "operations":[ { } ] } ], } 

Now we present an empty JSONObject inside the "operations" of a JSONArray. Therefore, this replaceAll function needs to be called again until the JSON String has any changes from the previous state.

Keep in mind that if you use functions like readLine () during data entry, it can remove the newline character, which will make this method inoperative. So decide that this will replace your read line with this.

 json += in.readLine() + '\n'; 

Here is a brief program I wrote that actually removes 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); } 
0
source

I don’t know about any built-in functions, but you can 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; } 

This will clear your json object from an empty field (it works recursively). Therefore, if JSON looks like this:

 "operations":[ { "nickname":"", "type":"", "responseMessages":[] }] 

the operation field will also be deleted.

Note: JSONArray.remove only works for API 19 above

0
source

In Scala, the org.json library can be easily converted to Java (albeit in a bit more detail). Recursively removes null 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 _ => } } } 
0
source

All Articles