2014-09-26 7 views
2

Я хочу, чтобы скопировать JSON полей из одного файла в другой, но только после того, как поле удовлетворяет определенному условию, как, например,Копирование отфильтрованных данных в формате JSON из одного файла в другой с помощью gson библиотеки в Java

{"dataset": 
    [ 
     {"album_id":1, 
     "album_type":"Live Performance", 
     "artist_name":"John Doe",.... 
     } 
    ] 
} 

Я хочу для копирования только тех записей, у которых есть имя пользователя или имя другого пользователя, иначе пропустите кортеж для копирования. Я использую следующий код, чтобы добавить отфильтрованные записи в JSONObject «wr», которые затем пишу в выходной файл. Но это не дает мне желаемых результатов

public static void dumpJSONElement(JsonElement element) { 
    if (element.isJsonObject()) { 
     JsonObject obj = element.getAsJsonObject(); 
     java.util.Set<java.util.Map.Entry<String,JsonElement>> entries = obj.entrySet(); 
     java.util.Iterator<java.util.Map.Entry<String,JsonElement>> iter = entries.iterator(); 
     while (iter.hasNext()) { 
      java.util.Map.Entry<String,JsonElement> entry = iter.next(); 
      if(entry.getKey().equals(filterKey)){ 
       if(! entry.getValue().toString().replace("\"", "").equals(filterValue)){ 
        wr.put(entry.getKey(), entry.getValue()); 
       } 
      } 
      else{ 
       wr.put(entry.getKey(), entry.getValue()); 
      } 
      dumpJSONElement(entry.getValue()); 
     } 

    } else if (element.isJsonArray()) { 
     JsonArray array = element.getAsJsonArray(); 
     java.util.Iterator<JsonElement> iter = array.iterator(); 
     while (iter.hasNext()) { 
      JsonElement entry = iter.next(); 
      dumpJSONElement(entry); 
     } 
    } else if (element.isJsonPrimitive()) { 
     JsonPrimitive value = element.getAsJsonPrimitive(); 

    } else if (element.isJsonNull()) { 

    } else { 
     System.out.println("Error. Unknown type of element"); 
    } 
} 
+0

Самое простое решение создать POJO, которые представляют вашу JSON, чем создавать Список с использованием библиотеки gson. и теперь, используя список, вы можете легко фильтровать. –

+0

Спасибо за опцию, но файлы json, которые я хочу обработать, предварительно не форматированы. Пользователь будет поставлять файл, поэтому вы не можете заранее получить json-архитектуру для POJO –

+0

, которую вы можете сделать, см. Ответ. –

ответ

2

используйте код ниже код, чтобы преобразовать вашу строку JSON для универсального типа Java List<Map<Object, Object>>, используйте код ниже.

import java.lang.reflect.Type; 
import java.util.List; 
import java.util.Map; 

import com.google.gson.Gson; 
import com.google.gson.reflect.TypeToken; 

public class Test { 
    public static void main(String... args) { 

    String str = "[{'id':1,'name':'yogesh'},{'id':2,'name':'aarush', 'degree': 'MCA'}]"; 

    Type type = new TypeToken<List<Map<Object, Object>>>() { 
    }.getType(); 

    List<Map<Object, Object>> list = new Gson().fromJson(str, type); 

    System.out.println(new Gson().toJson(list)); 
    filterList(list, "name", "yogesh"); 
    System.out.println(new Gson().toJson(list)); 

} 

public static void filterList(List<Map<Object, Object>> list, String key, Object value) { 
    for (Map<Object, Object> map : list) { 
     if (map.containsKey(key)) { 
      if (map.get(key).equals(value)) { 
       list.remove(map); 
      } 
     } 
    } 
} 
} 

сюда я фильтрd name = yogesh запись.

выхода:

[{"id":1.0,"name":"yogesh"},{"id":2.0,"name":"aarush","degree":"MCA"}] 
[{"id":2.0,"name":"aarush","degree":"MCA"}] 
+0

Спасибо за код, но он поддерживает только файл с одной глубиной, если я предоставляю такие данные, как [{'id': 1, 'attributes': [{'name': 'yogesh', 'age': 32}], {'id': 2, 'attributes': [{'name': 'aarush', 'age': 20}], 'degree': 'MCA'}], тогда он не может фильтровать, есть ли какое-либо обходное решение для обрабатывать глубину n-уровня в этом? –

+0

почему нет, в том же примере используйте: String str1 = "[{'id': 1, 'attributes': [{'name': 'yogesh', 'age': 32}]}, {'id': 2 , 'attributes': [{'name': 'aarush', 'age': 20}], 'degree': 'MCA'}] "; в этом случае ваш фильтр не будет работать, но вам нужно немного изменить метод filterList. –

0

Я имел аналогичные вопросы, и я гугл, много читал об этом. В заключение, лучший (наиболее эффективный) способ (с gson) - написать обычай TypeAdapter для вашего случая.

Вы можете проверить пример кода ниже (он работает, как вы ожидали):

public static void answer() { 

    String jsonAsText = "{\"dataset\":[{\"album_id\":1,\"album_type\":\"Live Performance\",\"artist_name\":\"John Doe\"},{\"album_id\":2,\"album_type\":\"A Dummy Performance\"}]}"; 

    GsonBuilder gsonBuilder = new GsonBuilder(); 
    gsonBuilder.registerTypeAdapter(List.class, new AlbumInfoListTypeAdapter()); 

    Gson gson = gsonBuilder.create(); 

    List<AlbumInfo> dataSet = gson.fromJson(jsonAsText, List.class); 

    System.out.println(gson.toJson(dataSet)); 
} 

private static class AlbumInfo { 
    int album_id; 
    String album_type; 
    String artist_name; 
} 

private static class AlbumInfoListTypeAdapter extends 
     TypeAdapter<List<AlbumInfo>> { 

    @Override 
    public List<AlbumInfo> read(com.google.gson.stream.JsonReader in) 
      throws IOException { 

     List<AlbumInfo> dataSet = new ArrayList<AlbumInfo>(); 

     in.beginObject(); 

     while (in.hasNext()) { 
      if ("dataset".equals(in.nextName())) { 
       in.beginArray(); 
       while (in.hasNext()) { 
        in.beginObject(); 
        AlbumInfo albumInfo = new AlbumInfo(); 

        while (in.hasNext()) { 
         String jsonTag = in.nextName(); 
         if ("album_id".equals(jsonTag)) { 
          albumInfo.album_id = in.nextInt(); 
         } else if ("album_type".equals(jsonTag)) { 
          albumInfo.album_type = in.nextString(); 
         } else if ("artist_name".equals(jsonTag)) { 
          albumInfo.artist_name = in.nextString(); 
         } 
        } 
        in.endObject(); 

        if (albumInfo.artist_name != null && !"".equals(albumInfo.artist_name.trim())) { 
         dataSet.add(albumInfo); 
        } else { 
         System.out.println("Album info ignored because it has no artist_name value"); 
        } 
       } 
       in.endArray(); 
      } 
     } 
     in.endObject(); 

     return dataSet; 
    } 

    @Override 
    public void write(com.google.gson.stream.JsonWriter out, 
      List<AlbumInfo> dataSet) throws IOException { 
     out.beginObject(); 

     out.name("dataset").beginArray(); 
     for (final AlbumInfo albumInfo : dataSet) { 
      out.beginObject(); 

      out.name("album_id").value(albumInfo.album_id); 
      out.name("album_type").value(albumInfo.album_type); 
      out.name("artist_name").value(albumInfo.artist_name); 

      out.endObject(); 
     } 
     out.endArray(); 

     out.endObject(); 
    } 
} 

Вы можете изменить read и write методы. У Гсона много интересных функций. Я настоятельно рекомендую вам прочитать образцы по адресу this link.

Edit:

Входящий текст в формате JSON:

{ 
    "dataset": [ 
    { 
     "album_id": 1, 
     "album_type": "Live Performance", 
     "artist_name": "John Doe" 
    }, 
    { 
     "album_id": 2, 
     "album_type": "A Dummy Performance" 
    } 
    ] 
} 

Выход на System.out.println в answer метода:

[ 
    { 
    "artist_name": "John Doe", 
    "album_type": "Live Performance", 
    "album_id": 1 
    } 
]