1

I am having JSON string as follows

String jtext= {"data":{"key1":"hello","key2":{"key21": [{"key211":"val1","key212":"val2","key213":"val3},{......},{.....}……..]}}

I am only interested in array inside key21. Is it possible to directly get the array inside key21?

I have tried the code below and it's working fine

JsonElement elementKey = new JsonParser().parse(jtext);
JsonObject eleObject = elementKey.getAsJsonObject();
JsonObject dataobj = eleObject.getAsJsonObject("data");

JsonObject key2= elementKey.getAsJsonObject("key2");
JsonArray jarray = data1.getAsJsonArray("key21");

So is it possible to directly penetrate into the JSON object to get array inside key21 in Gson ? I don't want whole linking from parent to get into the desired element or may be solution to minimize the LOC.

Arnaud
  • 7,259
  • 10
  • 50
  • 71
nikhil
  • 877
  • 3
  • 11
  • 36

2 Answers2

1

What you are asking for is pretty much exactly JSON Path, for which there is an implementation here. It has Gson support, but is marked as experimental. If all you are interested in is key-based navigation, not requiring support for handling array indices and whatnot, you can go with this significantly simpler (but more limited) option, as discussed on StackOverflow, where the author implements a recursive path evaluation method that walks down the element tree according to a dot-specified path: Using Gson with a path

Including such a method will give you your one-line-solution.

Community
  • 1
  • 1
llarsson
  • 11
  • 3
  • Welcome to SO @llarsson! When including links as a significant part of your answer it is considered good form to [summarize the link contents](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers). In this case that would apply to your "Using Gson with a path" link. Cheers! – eebbesen Jan 27 '15 at 13:12
1

This cuts out the first array under the given key so that the array can be parsed as usual JSON and not the whole String needs to be parsed. This works as long as there is no space between the key being looked for and the following :.

final String json = "{\"data\":{\"key1\":\"hello\",\"key2\":{\"key21\": [{\"key211\":\"val1\",\"key212\":\"val2\"}]}}";
final String key = "key21";

final StringBuilder sb = new StringBuilder();
//because first character after key might be a space
boolean started = false;
//as soon as all [ ] brackets opened after the key are
//closed again, the array has ended.
int brackets = 0;

final int first = json.indexOf("\"" + key + "\":"); //length of key + 3
char c;
for(int i = first + key.length() + 3; true; i++) {
    c = json.charAt(i);
    if(c == '[') {
        started = true;
        brackets++;
    } else if(c == ']') {
        brackets--;
    }
    sb.append(c);
    if(brackets == 0 && started) {
        break;
    }
}

// sb now contains only key21's array

And after this you can parse the JSON array in sb as you usually would.

MinecraftShamrock
  • 3,504
  • 2
  • 25
  • 44
  • thanks for your efforts.I appreciate that.:)cant mark as answer but can surely voteup as it could be one of the solution. – nikhil Jan 27 '15 at 14:43
  • Yes, it is surely not the perfect general solution, but for your case it seems to be the most efficient solution :) – MinecraftShamrock Jan 27 '15 at 14:53