有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java中json文档中指向叶节点的所有路径的输出列表

例如:给定这个json文档:

{
    "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
}

我想制作(类似)这样的输出:

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

我更喜欢基于一个健壮的json库(gson、jackson等)的高效解决方案,而不是从原始文本开始工作


共 (2) 个答案

  1. # 1 楼答案

    事实证明,使用Gson很容易做到这一点,尤其是使用JsonReader。2.3中介绍的getPath()方法

    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);
    
  2. # 2 楼答案

    下面是一个带有org.json的示例代码。但同样的方法也可以用于Gson/Jackson,并在这些库中更改相应的类型。这里的键也可以使用StringBuilder而不是字符串

    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);
      }
    
    }