先日、Jackson でJSON読込み key-value の BiConsumer を処理する - Oboe吹きプログラマの黙示録
Jackson でJSON読込み key-value の Stream生成 - Oboe吹きプログラマの黙示録
を書いたので、gson で同じことをします。
JSONキーは、"." で区切り、配列は、[n] でインデックスを表現します。
import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.util.AbstractMap.SimpleEntry; import java.util.Iterator; import java.util.Map.Entry; import java.util.function.BiConsumer; import java.util.function.Predicate; import java.util.stream.Stream; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; /** * JsonView */ public class JsonView{ public void read(String jsontxt, BiConsumer<String, Object> biconsumer){ parseElement(JsonParser.parseReader(new StringReader(jsontxt)), "", biconsumer); } public void read(Reader reader, BiConsumer<String, Object> biconsumer){ parseElement(JsonParser.parseReader(reader), "", biconsumer); } public void read(InputStream in, BiConsumer<String, Object> biconsumer){ parseElement(JsonParser.parseReader(new InputStreamReader(in, StandardCharsets.UTF_8)), "", biconsumer); } private void parseElement(JsonElement je, String parent, BiConsumer<String, Object> biconsumer){ if (je.isJsonObject()) { JsonObject jo = (JsonObject)je; for(Entry<String, JsonElement> e:jo.entrySet()){ parseElement(e.getValue(), parent + "." + e.getKey(), biconsumer); } }else if(je.isJsonArray()){ JsonArray ary = je.getAsJsonArray(); int i = 0; for(Iterator<JsonElement> it=ary.iterator();it.hasNext();i++){ parseElement(it.next(), parent + "[" + i + "]", biconsumer); } }else if(je.isJsonNull()){ biconsumer.accept(parent.substring(1), null); }else if(je.isJsonPrimitive()){ String path = parent.substring(1); JsonPrimitive p = je.getAsJsonPrimitive(); if (p.isNumber()){ if (je.toString().indexOf(".") > 0) { biconsumer.accept(path, p.getAsDouble()); }else{ if (p.getAsLong() <= Integer.MAX_VALUE) { biconsumer.accept(path, p.getAsLong()); }else{ biconsumer.accept(path, p.getAsInt()); } } }else if(p.isBoolean()){ biconsumer.accept(path, p.getAsBoolean()); }else if(p.isString()){ biconsumer.accept(path, p.getAsString()); } } } public void read(String jsontxt, Predicate<String> predicate, BiConsumer<String, Object> biconsumer){ parseElement(JsonParser.parseReader(new StringReader(jsontxt)), "", predicate, biconsumer); } public void read(Reader reader, Predicate<String> predicate, BiConsumer<String, Object> biconsumer){ parseElement(JsonParser.parseReader(reader), "", predicate, biconsumer); } public void read(InputStream in, Predicate<String> predicate, BiConsumer<String, Object> biconsumer){ parseElement(JsonParser.parseReader(new InputStreamReader(in, StandardCharsets.UTF_8)), "", predicate, biconsumer); } private void parseElement(JsonElement je, String parent, Predicate<String> predicate, BiConsumer<String, Object> biconsumer){ if (je.isJsonObject()) { JsonObject jo = (JsonObject)je; for(Entry<String, JsonElement> e:jo.entrySet()){ parseElement(e.getValue(), parent + "." + e.getKey(), biconsumer); } }else if(je.isJsonArray()){ JsonArray ary = je.getAsJsonArray(); int i = 0; for(Iterator<JsonElement> it=ary.iterator();it.hasNext();i++){ parseElement(it.next(), parent + "[" + i + "]", biconsumer); } }else if(je.isJsonNull()){ String path = parent.substring(1); if (predicate.test(path)){ biconsumer.accept(path, null); } }else if(je.isJsonPrimitive()){ String path = parent.substring(1); if (predicate.test(path)){ JsonPrimitive p = je.getAsJsonPrimitive(); if (p.isNumber()){ if (je.toString().indexOf(".") > 0) { biconsumer.accept(path, p.getAsDouble()); }else{ if (p.getAsLong() <= Integer.MAX_VALUE) { biconsumer.accept(path, p.getAsLong()); }else{ biconsumer.accept(path, p.getAsInt()); } } }else if(p.isBoolean()){ biconsumer.accept(path, p.getAsBoolean()); }else if(p.isString()){ biconsumer.accept(path, p.getAsString()); } } } } public Stream<Entry<String, Object>> stream(InputStream in){ Stream.Builder<Entry<String, Object>> builder = Stream.builder(); parseElement(JsonParser.parseReader(new InputStreamReader(in, StandardCharsets.UTF_8)), "", builder); return builder.build(); } public Stream<Entry<String, Object>> stream(String jsontxt){ Stream.Builder<Entry<String, Object>> builder = Stream.builder(); parseElement(JsonParser.parseReader(new StringReader(jsontxt)), "", builder); return builder.build(); } public Stream<Entry<String, Object>> stream(Reader reader){ Stream.Builder<Entry<String, Object>> builder = Stream.builder(); parseElement(JsonParser.parseReader(reader), "", builder); return builder.build(); } private void parseElement(JsonElement je, String parent, Stream.Builder<Entry<String, Object>> builder){ if (je.isJsonObject()) { JsonObject jo = (JsonObject)je; for(Entry<String, JsonElement> e:jo.entrySet()){ parseElement(e.getValue(), parent + "." + e.getKey(), builder); } }else if(je.isJsonArray()){ JsonArray ary = je.getAsJsonArray(); int i = 0; for(Iterator<JsonElement> it=ary.iterator();it.hasNext();i++){ parseElement(it.next(), parent + "[" + i + "]", builder); } }else if(je.isJsonNull()){ builder.add(new SimpleEntry<String, Object>(parent.substring(1), null)); }else if(je.isJsonPrimitive()){ String path = parent.substring(1); JsonPrimitive p = je.getAsJsonPrimitive(); if (p.isNumber()){ if (je.toString().indexOf(".") > 0) { builder.add(new SimpleEntry<String, Object>(path, p.getAsDouble())); }else{ if (p.getAsLong() <= Integer.MAX_VALUE) { builder.add(new SimpleEntry<String, Object>(path, p.getAsLong())); }else{ builder.add(new SimpleEntry<String, Object>(path, p.getAsInt())); } } }else if(p.isBoolean()){ builder.add(new SimpleEntry<String, Object>(path, p.getAsBoolean())); }else if(p.isString()){ builder.add(new SimpleEntry<String, Object>(path, p.getAsString())); } } } }
今頃になってこんなものと思いつつ、、
jsonview · yipuran/yipuran-gsonhelper Wiki · GitHub
として Git-Hub に入れた。もっと早く作ってればよかった。