For example: Given this json document:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
I would like to produce (something like) this output:
store.book.category: "reference"
store.book.author: "Nigel Rees"
store.book.title: "Sayings of the Century"
store.book.price: 8.95
store.book.category: "fiction"
store.book.author: "Herman Melville"
store.book.title: "Moby Dick"
store.book.isbn: "0-553-21311-3"
store.book.price: 8.99
store.bicycle.color: "red"
store.bicycle.price: 19.95
expensive:10
Rather than work from raw text, I would prefer an efficient solution based on one of the robust json libraries (gson, jackson, etc.).
Here is a sample code with org.json
. But the same can be used with Gson/Jackson with changes to appropriate types within those libraries. You could also using StringBuilder
instead of String for the keys here.
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONObject;
public class MyJSONTest {
private static void listJson(JSONObject json) {
listJSONObject("", json);
}
private static void listObject(String parent, Object data) {
if (data instanceof JSONObject) {
listJSONObject(parent, (JSONObject)data);
} else if (data instanceof JSONArray) {
listJSONArray(parent, (JSONArray) data);
} else {
listPrimitive(parent, data);
}
}
private static void listJSONObject(String parent, JSONObject json) {
Iterator it = json.keys();
while (it.hasNext()) {
String key = (String)it.next();
Object child = json.get(key);
String childKey = parent.isEmpty() ? key : parent + "." + key;
listObject(childKey, child);
}
}
private static void listJSONArray(String parent, JSONArray json) {
for (int i = 0; i < json.length(); i++) {
Object data = json.get(i);
listObject(parent + "[" + i + "]", data);
}
}
private static void listPrimitive(String parent, Object obj) {
System.out.println(parent + ":" + obj);
}
public static void main(String[] args) {
String data = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"NigelRees\",\"title\":\"SayingsoftheCentury\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"HermanMelville\",\"title\":\"MobyDick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99},],\"bicycle\":{\"color\":\"red\",\"price\":19.95}},\"expensive\":10}";
JSONObject json = new JSONObject(data);
System.out.println(json.toString(2));
listJson(json);
}
}
Turns out this is pretty easy to do using Gson, especially with the JsonReader.getPath() method introduced in 2.3.
static void parseJson(String json) throws IOException {
JsonReader reader = new JsonReader(new StringReader(json));
reader.setLenient(true);
while (true) {
JsonToken token = reader.peek();
switch (token) {
case BEGIN_ARRAY:
reader.beginArray();
break;
case END_ARRAY:
reader.endArray();
break;
case BEGIN_OBJECT:
reader.beginObject();
break;
case END_OBJECT:
reader.endObject();
break;
case NAME:
reader.nextName();
break;
case STRING:
String s = reader.nextString();
print(reader.getPath(), quote(s));
break;
case NUMBER:
String n = reader.nextString();
print(reader.getPath(), n);
break;
case BOOLEAN:
boolean b = reader.nextBoolean();
print(reader.getPath(), b);
break;
case NULL:
reader.nextNull();
break;
case END_DOCUMENT:
return;
}
}
}
static private void print(String path, Object value) {
path = path.substring(2);
path = PATTERN.matcher(path).replaceAll("");
System.out.println(path + ": " + value);
}
static private String quote(String s) {
return new StringBuilder()
.append('"')
.append(s)
.append('"')
.toString();
}
static final String REGEX = "\\[[0-9]+\\]";
static final Pattern PATTERN = Pattern.compile(REGEX);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With