JSONObject 删除空值对
Posted
技术标签:
【中文标题】JSONObject 删除空值对【英文标题】:JSONObject remove empty value pairs 【发布时间】:2015-09-11 09:39:24 【问题描述】:这是我的 Json 文件:
"models":,
"path":[
"path":"/web-profiles",
"operations":[
"type":"",
"responseMessages":[]
]
],
"produces":[]
如果键的值为空(包括 []、""、)。如何从 Json 文件中删除这些对。
-
我尝试使用 JSONObject 内置函数来删除不必要的对。但是,它不起作用。
我尝试使用字符串方法逐行处理。它有太多案例,我无法在我的代码中涵盖所有这些案例。 (例如,子键 'operations',当你想删除所有空值时,这个 key(operations) 值对也应该被删除。)
有什么想法吗?
【问题讨论】:
***.com/a/23921129/2369266 的可能重复项 【参考方案1】:首先,您应该将json
反序列化为Map<String, Object>
。
其次,循环映射条目以找出哪个键具有空值或哪个键具有值是ArrayList
的实例但为空并从Map
中删除。
最后,将Map
序列化为json
。
试试这个代码:
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);
【讨论】:
Type、TypeToken、GsonBuilder、Gson..这些api的任何jar..?【参考方案2】:正则表达式解决方案
在使用 JSONParser 解析数据之前,您可以使用 REGEX 从数据中删除包含 ""、[] 或 的任何行。
这样的正则表达式看起来像。请记住,您可能需要根据您的操作系统调整换行符
[^\n]*(\"(\n)*\"|\[(\n)*\]|\(\n)*\)[^\n]*
为了说明JSON数据如下的一个实例
"models":,
"path":[
"path":"/web-profiles",
"operations":[
"nickname":"",
"type":"",
"responseMessages":[]
]
],
"produces":[]
第一次运行 replaceAll 时,结果为
"path":[
"path":"/web-profiles",
"operations":[
]
],
现在我们在“操作”JSONArray 中创建了一个空的 JSONObject。所以需要再次调用这个 replaceAll 函数,直到 JSON 字符串与之前的状态没有任何变化。
请记住,如果您在数据输入期间使用 readLine() 之类的函数,它可能会删除换行符,这会使该方法不起作用。所以解决这个问题,用这个替换你的阅读行。
json += in.readLine() + '\n';
这是我编写的一个快速程序,它从原始字符串中实际删除空 json 对象。
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);
【讨论】:
【参考方案3】:如果您使用 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"]]
【讨论】:
【参考方案4】:不知道任何内置函数,但你可以试试这个
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;
这将从空字段中清除您的 json 对象(它以递归方式工作)。所以如果 JSON 看起来像这样:
"operations":[
"nickname":"",
"type":"",
"responseMessages":[]
]
字段“操作”也将被删除。
注意:JSONArray.remove 仅适用于以上 API 19
【讨论】:
【参考方案5】:在带有org.json
库的Scala 中,可以轻松地转换为Java(虽然有点冗长)。递归删除null
s 和空对象/数组:
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 _ =>
【讨论】:
【参考方案6】:这应该可以解决问题::
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);
【讨论】:
以上是关于JSONObject 删除空值对的主要内容,如果未能解决你的问题,请参考以下文章
如果一个json string中含有“class”这个key, 那么利用JSONObjec.fromObject(string)得到的一个json object会丢失“class”信息
保留空值——Java POJO 到 org.JSONObject