web-dev-qa-db-ja.com

JSONObjectは空の値のペアを削除します

これが私のJsonファイルです:

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

キーの値が空の場合([]、 ""、{}を含む)。これらのペアをJsonファイルから削除するにはどうすればよいですか。

  1. JSONObject組み込み関数を使用して、不要なペアを削除しようとしました。しかし、それはうまくいきませんでした。
  2. 文字列メソッドを使用して1行ずつ処理しようとしました。ケースが多すぎて、コードでそれらすべてのケースをカバーすることはできません。 (たとえば、サブキー「操作」、空の値をすべて削除する場合は、このキー(操作)値のペアも削除する必要があります。)アイデアはありますか?
7

まず、jsonMap<String, Object>に逆シリアル化する必要があります。次に、マップエントリをループして、どのキーにnull値があるか、またはどのキーに値があるかを確認します。これはArrayListのインスタンスですが、空であり、Mapから削除します。最後に、Mapjsonにシリアル化します。

このコードを試してください:

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
codeaholicguy

正規表現ソリューション

JSONParserで解析する前に、REGEXを使用して、「」、[]、または{}を含む行をデータから削除できます。

このようなものの正規表現は次のようになります。 OSによっては、改行文字を調整する必要がある場合があることに注意してください。

[^\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);
}
1
egtoney

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
saka1029

組み込み関数についてはわかりませんが、これを試すことができます

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は、上記のAPI19でのみ機能します

0
fchristysen

In Scala with org.jsonライブラリは、Java(もう少し冗長ですが)に簡単に変換できます。nullsと空のオブジェクト/配列を再帰的に削除します:

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
Leon Stein

これでうまくいくはずです::

                        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);
                            }
                        }
0
Johnny Alpha