【问题标题】:Best way to parse JSON with an unknown structure for comparison with a known structure?解析具有未知结构的 JSON 以与已知结构进行比较的最佳方法?
【发布时间】:2019-06-12 11:49:49
【问题描述】:

我有一个 YAML 文件,我将其转换为 JSON,然后使用 GSON 转换为 Java 对象。这将用作标准定义,我将与其他 YAML 文件进行比较。我将验证的 YAML 文件应包含与我的定义具有相同结构的字段。但是,它很可能包含具有不同结构的字段,以及我的定义中不存在的字段,因为最终由用户在我收到文件之前创建这些字段。 YAML 中要验证的字段可能如下所示,可以选择用户希望定义的嵌套级别。

 LBU:
      type: nodes.Compute
      properties:
        name: LBU
        description: LBU
        configurable_properties: 
          test: {"additional_configurable_properties":{"aaa":"1"}}
        vdu_profile:
          min_number_of_instances: 1
          max_number_of_instances: 4
      capabilities:
        virtual_compute:
          properties:
            virtual_memory:
              virtual_mem_size: 8096 MB
            virtual_cpu:
              cpu_architecture: x86
              num_virtual_cpu: 2
              virtual_cpu_clock: 1800 MHz
      requirements:
      - virtual_storage:
          capability: capabilities.VirtualStorage
          node: LBU_Storage        

目前,我收到此 YAML 文件并将其转换为带有 Gson 的 JsonObject。由于存在任何可能的未知字段,因此无法将其映射到 Java 对象。我的目标是遍历这个文件,并根据我的定义中的匹配字段来验证每个字段。如果存在定义中不存在的字段,或者确实存在但具有不同的属性,我需要通知用户有关该字段的特定信息。

到目前为止,我正在走这样的路线。

 for (String field : obj.get("topology_template").getAsJsonObject().get("node_template").getAsJsonObject().get(key).getAsJsonObject().get(
              obj.get("topology_template").getAsJsonObject().get("node_templates").getAsJsonObject().get(key).getAsJsonObject().keySet().toArray()[i].toString()).getAsJsonObject().keySet()) {

但是,这似乎有点过分,对于一些深度嵌套的字段来说很难遵循。

我想知道的是,是否有一种更简单的方法来遍历 JsonObject 的每个字段,而不将其映射到 Java 对象,并且无需通过名称显式访问每个字段?

【问题讨论】:

    标签: java json gson


    【解决方案1】:

    我认为您正在寻找类似流式 Json Parser 的东西:

    这是一个例子

    String json
      = "{\"name\":\"Tom\",\"age\":25,\"address\":[\"Poland\",\"5th avenue\"]}";
    JsonFactory jfactory = new JsonFactory();
    JsonParser jParser = jfactory.createParser(json);
    
    String parsedName = null;
    Integer parsedAge = null;
    List<String> addresses = new LinkedList<>();
    
    while (jParser.nextToken() != JsonToken.END_OBJECT) {
        String fieldname = jParser.getCurrentName();
        if ("name".equals(fieldname)) {
            jParser.nextToken();
            parsedName = jParser.getText();
        }
    
        if ("age".equals(fieldname)) {
            jParser.nextToken();
            parsedAge = jParser.getIntValue();
        }
    
        if ("address".equals(fieldname)) {
            jParser.nextToken();
            while (jParser.nextToken() != JsonToken.END_ARRAY) {
                addresses.add(jParser.getText());
            }
        }
    }
    jParser.close();
    

    请在此处找到文档: https://github.com/FasterXML/jackson-docs/wiki/JacksonStreamingApi

    【讨论】:

      猜你喜欢
      • 2017-03-18
      • 1970-01-01
      • 2019-05-28
      • 2017-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      相关资源
      最近更新 更多