比较重度嵌套的Json并打印出结构和值的差异

问题描述 投票:0回答:2

我有一个重度嵌套的json,必须进行比较。比较指的是结构(字段)相同且值相等。我还想打印出价值和结构的差异。是否有一个Java库可以帮助这个开箱即用?

java json comparison
2个回答
0
投票

我为电子游戏写了类似的东西。这是我使用的代码。它利用了Ox中的Json库

  private Json computeDiff(Json a, Json b) {
    Json ret = Json.object();
    for (String key : b) {
      if (a.hasKey(key)) {
        Object aVal = a.getObject(key);
        Object bVal = b.getObject(key);

        if (aVal instanceof Json && ((Json) aVal).isObject()) {
          Json innerJson = computeDiff((Json) aVal, (Json) bVal);
          if (innerJson.size() > 0) {
            ret.with(key, innerJson);
          }
        } else {
          if (aVal.equals(bVal)) {
            continue;
          }

          ret.with(key, b.getObject(key));
        }
      } else {
        ret.with(key, b.getObject(key));
      }
    }
    for (String key : a) {
      if (!b.hasKey(key)) {
        // this element got deleted
        ret.with(key, "<DELETED>");
      }
    }
    return ret;
  }

0
投票

Gson图书馆的实施:

public static void compareJson(JsonElement json, JsonElement other) {
    compareJson(json, other, "");
}

private static void compareJson(JsonElement json, JsonElement other, String path) {
    if (json.equals(other)) return;

    if (json.isJsonArray() && other.isJsonArray()) {
        JsonArray arrJ = (JsonArray) json;
        JsonArray arrO = (JsonArray) other;

        int size = Math.min(arrJ.size(), arrO.size());
        for (int i = 0; i < size; i++) {
            compareJson(arrJ.get(i), arrO.get(i), path + "/" + i);
        }
        if (arrJ.size() > arrO.size()) {
            for (int i = arrO.size(); i < arrJ.size(); i++) {
                System.out.println(path + "/ deleted array value: " + arrJ.get(i));
            }
        } else if (arrJ.size() < arrO.size()) {
            for (int i = arrJ.size(); i < arrO.size(); i++) {
                System.out.println(path + "/ added array value: " + arrO.get(i));
            }
        }
    } else if (json.isJsonObject() && other.isJsonObject()) {
        JsonObject objJ = (JsonObject) json;
        JsonObject objO = (JsonObject) other;

        for (Entry<String, JsonElement> entry : objJ.entrySet()) {
            String key = entry.getKey();
            JsonElement value = entry.getValue();
            if (objO.has(key)) {
                compareJson(value, objO.get(key), path + "/" + key);
            } else {
                System.out.println(path + "/ deleted object entry: \"" + key + "\": " + value);
            }
        }
        for (Entry<String, JsonElement> entry : objO.entrySet()) {
            String key = entry.getKey();
            JsonElement value = entry.getValue();
            if (!objJ.has(key)) {
                System.out.println(path + "/ added object entry: \"" + key + "\": " + value);
            }
        }
    } else if (json.isJsonPrimitive() && other.isJsonPrimitive()) {
        System.out.println(path + "/ value changed: " + json + " -> " + other);
    } else {
        System.out.println(path + "/ element changed: " + json + " -> " + other);
    }
}

使用:

JsonParser parser = new JsonParser();
compareJson(parser.parse(json1), parser.parse(json2));

示例输出:

/glossary/title/ value changed: "example glossary" -> "Example Glossary"
/glossary/GlossDiv/GlossList/GlossEntry/SortAs/ element changed: "SGML" -> null
/glossary/GlossDiv/GlossList/GlossEntry/GlossDef/GlossSeeAlso/0/ value changed: "GML" -> "XML"
/glossary/GlossDiv/GlossList/GlossEntry/GlossDef/GlossSeeAlso/ deleted array value: "XML"
/glossary/GlossDiv/GlossList/GlossEntry/ deleted object entry: "GlossSee": "markup"
/glossary/GlossDiv/GlossList/GlossEntry/ added object entry: "GlossType": "markup"
© www.soinside.com 2019 - 2024. All rights reserved.