先日、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 に入れた。もっと早く作ってればよかった。