これが私のJsonファイルです:
{
"models":{},
"path":[
{
"path":"/web-profiles",
"operations":[
{
"type":"",
"responseMessages":[]
}
]
}
],
"produces":[]
}
キーの値が空の場合([]、 ""、{}を含む)。これらのペアをJsonファイルから削除するにはどうすればよいですか。
まず、json
をMap<String, Object>
に逆シリアル化する必要があります。次に、マップエントリをループして、どのキーにnull値があるか、またはどのキーに値があるかを確認します。これは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);
正規表現ソリューション
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);
}
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"}]}]}
}
組み込み関数についてはわかりませんが、これを試すことができます
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でのみ機能します
In Scala with org.json
ライブラリは、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 _ =>
}
}
}
これでうまくいくはずです::
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);
}
}