Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Gson with a path

Using a simple Json file e.g:

{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}

I want to be able to get the JsonArray named menuitem using a path:

String path =  "menu.popup.menuitem"

I tried to do this using:

public static JsonElement fromString(String json, String path) throws JsonSyntaxException {
        JsonObject obj = GsonBuilder.create().fromJson(json, JsonObject.class);
        String[] seg = path.split(".");
        for (String element : seg) {
            if (obj != null) {
                obj = obj.get(element).getAsJsonObject();
            } else {
                return null;
            }
        }
        return obj
}

with:

JsonElement jsonElement = fromString(json, path);

But when I try isJsonArray() the return value is false. When doing the extra sanity check using Gson.toJson(jsonElement) the output is the full json String (above) that was inputted originally. What's going wrong?

like image 314
Eduardo Avatar asked Sep 28 '14 17:09

Eduardo


People also ask

What is the difference between GSON and JSON?

The JSON format was originally specified by Douglas Crockford. On the other hand, GSON is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object.

What is the difference between GSON and Jackson?

Both Gson and Jackson are good options for serializing/deserializing JSON data, simple to use and well documented. Advantages of Gson: Simplicity of toJson/fromJson in the simple cases. For deserialization, do not need access to the Java entities.


1 Answers

I'm not sure why this is not built-into Gson, but here is a method that I wrote, which returns a JsonElement given a JsonElement input and a JSON Path:

/**
 * Returns a JSON sub-element from the given JsonElement and the given path
 *
 * @param json - a Gson JsonElement
 * @param path - a JSON path, e.g. a.b.c[2].d
 * @return - a sub-element of json according to the given path
 */
public static JsonElement getJsonElement(JsonElement json, String path){

    String[] parts = path.split("\\.|\\[|\\]");
    JsonElement result = json;

    for (String key : parts) {

        key = key.trim();
        if (key.isEmpty())
            continue;

        if (result == null){
            result = JsonNull.INSTANCE;
            break;
        }

        if (result.isJsonObject()){
            result = ((JsonObject)result).get(key);
        }
        else if (result.isJsonArray()){
            int ix = Integer.valueOf(key) - 1;
            result = ((JsonArray)result).get(ix);
        }
        else break;
    }

    return result;
}

To call it, use something like:

String jsonString = ...;

Gson gson = new Gson();
JsonObject  jsonObject = gson.fromJson(jsonString, JsonObject.class);
JsonElement subElement = getJsonElement(jsonObject, "a.b.c[2].d";
like image 50
isapir Avatar answered Oct 04 '22 03:10

isapir