Json key with “.” as separator

荒凉一梦 提交于 2021-01-27 17:31:32

问题


I am using JSON to save settings and load them again after a restart. But now I want to use keys like "category.subcategory.variable" to get the value. I imagine something like

boolean foo = json.get("category.subcategory.foo");
String bar = json.get("category.bar");
json.set("category.subcategory.baz", baz);

and the json looks like this

{
    category: {
        subcategory: {
            foo: false,
            baz: ["baz"]
        },
        bar: "bar"
    }
}

I'm also using Gson, maybe it is possible there, but if it is only possible with another library I could think about adding it.

I hope someone of you know more than me, it's the first time that I use JSON in Java...


回答1:


I would implement something like:

public static String parse(String key,String json ){
        String[] array=key.split("\\.");
        JsonElement jsonElement = new JsonParser().parse(json);
        String result=null;
        JsonObject  jobject=null;
        String currentKey = null;
        try{for(int i=0;i<array.length;i++){
            currentKey=array[i];
            JsonElement jelement = new JsonParser().parse(jsonElement.toString());
              jobject = jelement.getAsJsonObject();
            if(jobject.isJsonObject()&&!jobject.isJsonPrimitive()) {
            jobject = jobject.getAsJsonObject(array[i]);}
            else {
                return jobject.get(array[i]).toString();
            }
            result=jobject.toString();
            jsonElement=jobject;
        }}catch(ClassCastException e) {
        return jobject.get(currentKey).toString();
        }
        return result;
    }



回答2:


I made it by myself and I use JsonObject for this. My tests worked and I hope I won't find any error. Because I want to manage some settings with it my initial JsonObject is called "settings".

JsonObject settings;
JsonObject defaultSettings;

static JsonElement getSetting(String key){
    String[] args = key.split("\\.");
    JsonObject curr = settings;
    for(int i = 0; i < args.length - 1; i++){
        curr = curr.getAsJsonObject(args[i]);
    }
    if(curr.has(args[args.length - 1]))
        return curr.get(args[args.length - 1]);
    else
        return getGuildSetting(gId, key, defaultSettings);
}
static JsonElement getSetting(String key, JsonObject jsonObject){
    String[] args = key.split("\\.");
    JsonObject curr = jsonObject;
    for(int i = 0; i < args.length - 1; i++){
        curr = curr.getAsJsonObject(args[i]);
    }
    return curr.get(args[args.length - 1]);
}

static void setSetting(String key, Object val){
    String[] args = key.split("\\.");
    JsonElement emptyElement = new Gson().fromJson("{}", JsonElement.class);
    JsonObject curr = settings;
    for(int i = 0; i < args.length - 1; i++){
        if(!curr.keySet().contains(args[i])) curr.add(args[i], emptyElement);
        curr = curr.getAsJsonObject(args[i]);
    }
    curr.add(args[args.length - 1], new Gson().toJsonTree(val));
}

Maybe there is a better way to test if it is a number, but seems like an integer isn't a number... And I tried converting the object itself to a JsonElement, but that didn't work. So you can only use numbers, booleans, strings and characters, bacause that are the functions JsonObject lets you use.

EDIT: ok I'm dumb. Instead of using val.getClass() == Number.class etc I can use val instanceof Number and that is true for all kind of numbers. That's why I changed the code.

EDIT 2: ok I'm really dumb. there is a function that only uses an object and nothing more...



来源:https://stackoverflow.com/questions/53508491/json-key-with-as-separator

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!