JSONObject删除空值对

时间:2015-06-25 00:10:51

标签: java json string format jsonobject

这是我的Json文件:

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

如果键的值为空(包括[],“”,{})。如何从Json文件中删除这些对。

  1. 我尝试使用JSONObject内置函数来删除不必要的对。但是,它没有用。
  2. 我尝试使用字符串方法逐行处理它。它有太多的情况,我不能在我的代码中涵盖所有这些情况。 (例如,子键'operations',当你想删除所有空值时,也应该删除这个键(操作)值对。) 有什么想法吗?

6 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

如果您使用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"}]}]}
}

答案 2 :(得分:0)

正则表达式解决方案

在使用JSONParser解析之前,您可以使用REGEX从数据中删除包含&#34;&#34;,[]或{}的任何行。

像这样的东西的正则表达式看起来像。请记住,您可能需要根据操作系统调整新行字符

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

考虑JSON数据如下的实例

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

第一次运行replaceAll时,它将以

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

现在我们在&#34;操作&#34;内部有一个空的JSONObject。 JSONArray。因此,需要再次调用此replaceAll函数,直到JSON字符串没有从它之前的状态进行任何更改。

请记住,如果在数据输入期间使用readLine()等函数,则可以删除换行符,这会使此方法无效。所以解决这个用这个替换你的读取线。

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

这是我编写的一个快速程序,用于从原始String中实际删除空的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 :(得分:0)

不知道任何内置函数,但你可以试试这个

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

那会从空字段清理你的json对象(它递归地工作)。所以,如果JSON看起来像这样:

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;
}

字段&#34;操作&#34;也将被删除。

注意:JSONArray.remove仅适用于上面的API 19

答案 4 :(得分:0)

在带有org.json库的Scala中,可以很容易地转换为Java(尽管有点冗长)。递归删除null和空对象/数组:

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 _ =>
    }
  }

}

答案 5 :(得分:0)

这可以达到目的::

                        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);
                            }
                        }