2015-06-25 21 views
5

Ecco il mio file JSON:JSONObject rimuovere coppie di valori vuoti

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

Se i valori delle chiavi sono vuoti (include [], "", {}). Come posso rimuovere quelle coppie dal file Json.

  1. Ho provato a utilizzare le funzioni di JSONObject per rimuovere coppie non necessarie. Ma non ha funzionato.
  2. Ho provato a utilizzare il metodo stringa per elaborarlo riga per riga. Ha troppi casi, non posso coprire tutti questi casi nel mio codice. (ad esempio, la sottochiave "operazioni", quando si desidera rimuovere tutto il valore vuoto, anche questa coppia di valori chiave (operazioni) dovrebbe essere rimossa.) Qualche idea?
+1

possibili duplicati di http://stackoverflow.com/a/23921129/2369266 –

risposta

1

In primo luogo, è necessario deserializzare json in un Map<String, Object>. In secondo luogo, eseguire il ciclo della voce della mappa per scoprire quale chiave ha valore null o quale chiave ha valore è istanza di ArrayList ma vuota e rimossa dallo Map. Infine, serializzare Map in json.

Prova di questo codice:

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); 
+0

tipo, TypeToken, GsonBuilder, GSON .. qualsiasi vaso per queste api ..? –

+0

@ReyRajesh è possibile cercare Gson o vedere qui https://github.com/google/gson – codeaholicguy

0

soluzione Regex

Si potrebbe utilizzare REGEX per rimuovere qualsiasi linea dai dati che conatins un "", [], o {} prima si analizza lo con JSONParser.

Il regex per qualcosa di simile sarebbe simile. Tenete a mente che potrebbe essere necessario regolare il carattere di nuova riga seconda del sistema operativo

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

Per tenere conto di un caso in cui i dati JSON è la seguente

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

La prima volta che si esegue che replaceAll il risultato sarà con

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

Ora abbiamo una JSONObject vuoto all'interno delle "operazioni" JSONArray. Quindi questa funzione replaceAll deve essere chiamata di nuovo fino a quando la stringa JSON non ha alcuna modifica dal suo stato precedente.

Ricordare che se si utilizzano funzioni come readLine() durante l'immissione dei dati, è possibile rimuovere il carattere di fine riga che renderà questo metodo non funzionante. Quindi risolvere questo sostituisci la tua riga di lettura con questo.

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

Ecco un rapido programma che ho scritto che esegue la rimozione effettiva di oggetti JSON vuoti dalla stringa originale.

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

Se si utilizza 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"}]}]} 
} 
0

non conoscono alcuna funzione build-in, ma si potrebbe provare questo

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

Che sarebbe pulire l'oggetto JSON da campo vuoto (funziona in modo ricorsivo). Quindi, se il JSON appare così:

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

campo "operazioni" anche rimosso.

nota: JSONArray.remove funzionano solo per API 19 sopra

0

In Scala con org.json libreria, può essere facilmente convertito in Java (anche se un po 'più dettagliato). rimuove ricorsivamente null s ed oggetti vuoti/matrici:

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

} 
Problemi correlati