java - 使用 json 模板文件和 json 数据文件构建新的 json 字符串

标签 java json gson

我有一个如下的 json 模板文件

{
  "value": "abc",
  "Treatments": [{
    "value": "def",
    "Stages": [{
      "value": "ghi"
    }]
  }]
}

还有一个json数据

{ "abc": {
    "labelabc": "Assembly name abc",
    "typeabc": "STRING_TYPE abc",
    "formatabc": "N abc"
  },
  "def": {
    "labeldef": "Assembly name def",
    "typedef": "STRING_TYPE def",
    "formatdef": "N def"
  },
  "ghi": {
    "labelghi": "Assembly name ghi",
    "typeghi": "STRING_TYPE ghi",
    "formatghi": "N ghi"
  }
}

我正在寻找一种将模板解析为

的解决方案
{
  "labelabc": "Assembly name abc",
  "typeabc": "STRING_TYPE abc",
  "formatabc": "N abc",
  "Treatments": [
    {
      "labeldef": "Assembly name def",
      "typedef": "STRING_TYPE def",
      "formatdef": "N def",
      "Stages": [
        {
          "labelghi": "Assembly name ghi",
          "typeghi": "STRING_TYPE ghi",
          "formatghi": "N ghi"
        }
      ]
    }
  ]
}

意思是:

  • 将“value”条目替换为 json 数据文件中的 jsonobject 值

我已经使用下面的代码通过 2 级模板实现了结果。但以上 3 个级别的模板失败了

public static JsonElement generateTemplate(JsonElement templateJson, JsonElement dataTemplate) {
if (templateJson.isJsonArray()) {
            for (JsonElement jsonElement1 : templateJson.getAsJsonArray()) {
                generateTemplate(jsonElement1, dataTemplate);
            }
        } else if (templateJson.isJsonObject()) {
            for (Iterator<Map.Entry<String, JsonElement>> iterator = templateJson.getAsJsonObject().entrySet()
                    .iterator(); iterator.hasNext();) {
                Map.Entry<String, JsonElement> entry = iterator.next();
                if (entry.getKey().equals("value")) {
                    templateJson = dataTemplate.getAsJsonObject().get(entry.getValue().getAsString()).getAsJsonObject();
                } else {
                    if (entry.getValue().isJsonObject()) {
                        generateTemplate(entry.getValue(), dataTemplate);
                    } else
                        templateJson.getAsJsonObject().add(entry.getKey(), p.parse(
                            dataTemplate.getAsJsonObject().get(entry.getValue().getAsString()).getAsJsonObject()
                                ));
                }

                generateTemplate(entry.getValue(), dataTemplate);
            }
        }

return templateJson;
}

非常感谢您的建议

最佳答案

您可以使用递归。这是主要思想,您可以稍后在 modifyObject 方法中根据您的需要调整实际替换,对于 "value": "abc" 将期望对象保存在 data 中

"abc": {
    "labelabc": "Assembly name abc",
    "typeabc": "STRING_TYPE abc",
    "formatabc": "N abc"
}
private static void modifyObject(JsonObject obj, JsonObject replacement) {
    obj.remove("value");
    for (String key : replacement.keySet()) {
        obj.addProperty(key, replacement.get(key).getAsString());
    }
}

public static JsonElement traverse(JsonElement element, JsonObject allReplacements) {
    if (element.isJsonObject()) {
        JsonObject asJsonObject = element.getAsJsonObject();
        ///keys can change after we modify object,
        //but we want to iterate only over original keys
        Set<String> originalKeys = new HashSet<>(asJsonObject.keySet());
        for (String key : originalKeys) {
            if (key.equals("value")) {
                String value = asJsonObject.get(key).getAsString();
                modifyObject(asJsonObject, allReplacements.getAsJsonObject(value));
            } else {
                traverse(asJsonObject.get(key), allReplacements);
            }
        }
    } else if (element.isJsonArray()) {
        for (JsonElement innerElement : element.getAsJsonArray()) {
            traverse(innerElement, allReplacements);
        }
    }
    return element;
}

用法:

public static void main(String[] args) throws Exception {
    String jsonTemplate =
            "{\n" +
            "  \"value\": \"abc\",\n" +
            "  \"foo\": \"bar\",\n" +
            "  \"Treatments\": [ {\n" +
            "    \"value\": \"def\",\n" +
            "    \"Stages\": [ [ {\n" +
            "      \"value\": \"ghi\"\n" +
            "    } ] ]\n" +
            "  } ]\n" +
            "}";
    String jsonData = "{ \"abc\": {\n" +
            "    \"label\": \"Assembly name abc\",\n" +
            "    \"type\": \"STRING_TYPE abc\",\n" +
            "    \"format\": \"N\"\n" +
            "  },\n" +
            "  \"def\": {\n" +
            "    \"label\": \"Assembly name def\",\n" +
            "    \"type\": \"STRING_TYPE\",\n" +
            "    \"format\": \"N\"\n" +
            "  },\n" +
            "  \"ghi\": {\n" +
            "    \"label\": \"Assembly name ghi\",\n" +
            "    \"type\": \"STRING_TYPE\",\n" +
            "    \"format\": \"N\"\n" +
            "  }\n" +
            "}";


    JsonParser jsonParser = new JsonParser();
    JsonElement template = jsonParser.parse(jsonTemplate);
    JsonObject data = (JsonObject) jsonParser.parse(jsonData);

    JsonElement obj = template.deepCopy();//in case we don't want to modify original template

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    System.out.println(gson.toJson(traverse(obj, data)));

}

输出:

{
  "foo": "bar",
  "Treatments": [
    {
      "Stages": [
        [
          {
            "label": "Assembly name ghi",
            "type": "STRING_TYPE",
            "format": "N"
          }
        ]
      ],
      "label": "Assembly name def",
      "type": "STRING_TYPE",
      "format": "N"
    }
  ],
  "label": "Assembly name abc",
  "type": "STRING_TYPE abc",
  "format": "N"
}

关于java - 使用 json 模板文件和 json 数据文件构建新的 json 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56175923/

相关文章:

javascript - 我如何处理 jQuery.Ajax 中的时间响应(数据类型 : JSON)?

json - Docker - 使用 SystemD 和 "daemon.json"启用远程 HTTP API

python - 如何将 json 导入为 dict?

php - 在 PHP 中将对象转换为 JSON 并将 JSON 转换为对象,(像 Gson for Java 之类的库)

android - Retrofit2 将图像发布为 base64

java - Android 共享首选项

java - 递归方法中的后递增?

JAVA - 在字符串ArrayList中查找相似的单词

java - 创建 POJO 以匹配 JSON 结构

java - 重定向Android中C程序的STDIN和STDOUT