Java JsonPath: изменить несколько атрибутов JSON одновременно - PullRequest
0 голосов
/ 30 августа 2018

Я пытаюсь изменить несколько объектов JSON, используя библиотеку JsonPath . У меня есть селектор, который объявляется во время выполнения и JSON-файл неизвестного размера. Я хочу изменить только объекты JSON, которые соответствуют критериям фильтра, определяемым селектором. В этом примере все объекты получают новый ключ: joinedName = firstName + ‘ ‘ + lastName (кроме объекта Боба). Я заставил это работать, но у меня есть чувство, что должен быть лучший способ сделать это. Пожалуйста, дайте мне знать, как улучшить мой обходной путь. Спасибо!

@Test
public void addMultipleValuesAtOnce() throws JSONException {

    String json = "{\n" +
            "\"jsonArr\": [\n" +
            "   {\n" +
            "       \"firstName\":\"Alice\",\n" +
            "       \"lastName\":\"Smith\"\n" +
            "   },\n" +
            "   {\n" +
            "       \"firstName\":\"Bob\",\n" +
            "       \"lastName\":\"Williams\"\n" +
            "   },\n" +
            "   {\n" +
            "       \"firstName\":\"Carol\",\n" +
            "       \"lastName\":\"Johnson\"\n" +
            "   }\n" +
            "   ]\n" +
            "}";

    System.out.println("------------- IN --------------");
    System.out.println(json);
    DocumentContext parse = JsonPath.parse(json);

    final String selector = "$.jsonArr[?(!(@.firstName == 'Bob'))]"; // select every entry, except BOB's

    net.minidev.json.JSONArray firstNames = parse.read(selector + ".firstName");
    net.minidev.json.JSONArray lastNames = parse.read(selector + ".lastName");

    //HACK
    {
        String[] joinedNames = new String[firstNames.toArray().length];
        for (int i = 0; i < joinedNames.length; i++) {
            joinedNames[i] = firstNames.get(i) + " " + lastNames.get(i);
        }

        parse.put(selector, "joinedName", null); // add key
        final AtomicReference<Integer> counter = new AtomicReference<>(0);
        parse.map(selector + ".joinedName", (o, configuration) -> {
           return joinedNames[counter.getAndUpdate(x -> x + 1)];
        });
    }

    System.out.println("------------- OUT --------------");
    System.out.println(parse.jsonString());

    // The expected values:
    Assert.assertEquals("Alice Smith", parse.read("$.jsonArr[0].joinedName"));
    Assert.assertEquals("Carol Johnson", parse.read("$.jsonArr[2].joinedName"));
}
...