Сравните сильно вложенный Json и распечатайте разницу в структуре и стоимости - PullRequest
0 голосов
/ 25 апреля 2019

У меня сильно вложенный JSON, который нужно сравнить. Сравнение относится к тому, что структурные (поля) одинаковы, а значения равны. Я также хочу распечатать различия в стоимости и структуре. Есть ли библиотека Java, которая может помочь это из коробки?

Ответы [ 2 ]

0 голосов
/ 25 апреля 2019

Реализация для 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"
0 голосов
/ 25 апреля 2019

Я написал нечто подобное для видеоигры.Вот код, который я использовал.Он использует библиотеку Json внутри Ox

  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;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...