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?
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:
To call it, use something like:
split
uses regex to find places on which string should be split, but.
in regex is special character which represents "any character beside line separators", which means that you are actually splitting on each character. So for string like"foo".split(".")
will split onf
,o
,o
which means you will get as result array with four empty strings (3 splits give 4 elements).
Actually I lied here because
split(regex)
does one additional thing: it removes trailing empty strings from result array, but your array contains only empty strings, which means that they will all be removed, sosplit(".")
will return just empty array[]
so your loop will not iterate even once (that is why your method returns unmodifiedobj
).To get rid of this problem you will need to make
.
literal (you need to escape it). To do so you can use for instancesplit("\\.")
orsplit("[.]")
orsplit(Pattern.quote(".")
which work same assplit("\\Q.\\E")
- it adds quotation area.Also inside loop you should first check type of Json you are handling, because
getAsJsonObject
will fail if Json is array. So your code should probably look like