17

My goal is to update some textual fields in a JsonNode.

    List<JsonNode> list = json.findValues("fieldName");
    for(JsonNode n : list){
        // n is a TextNode. I'd like to change its value.
    }

I don't see how this could be done. Do you have any suggestion?

yo_haha
  • 359
  • 1
  • 4
  • 15
  • 1
    Did you see http://stackoverflow.com/questions/17967531/jackson-api-partially-update-a-string – Semih Eker Feb 19 '15 at 13:18
  • I don't have POJO that represents my Json. Do I really need to do all that in order to update a simple textNode??!! – yo_haha Feb 19 '15 at 14:22
  • See also: http://wiki.fasterxml.com/JacksonHowToCustomDeserializers and http://www.baeldung.com/jackson-deserialization – Dave Jarvis Sep 23 '16 at 01:46

2 Answers2

31

The short answer is: you can't. TextNode does not expose any operations that allows you to alter the contents.

With that being said, you can easily traverse the nodes in a loop or via recursion to get the desired behaviour. Imagine the following:

public class JsonTest {
    public static void change(JsonNode parent, String fieldName, String newValue) {
        if (parent.has(fieldName)) {
            ((ObjectNode) parent).put(fieldName, newValue);
        }

        // Now, recursively invoke this method on all properties
        for (JsonNode child : parent) {
            change(child, fieldName, newValue);
        }
    }

    @Test
    public static void main(String[] args) throws IOException {
        String json = "{ \"fieldName\": \"Some value\", \"nested\" : { \"fieldName\" : \"Some other value\" } }";
        ObjectMapper mapper = new ObjectMapper();
        final JsonNode tree = mapper.readTree(json);
        change(tree, "fieldName", "new value");
        System.out.println(tree);
    }
}

The output is:

{"fieldName":"new value","nested":{"fieldName":"new value"}}

wassgren
  • 18,651
  • 6
  • 63
  • 77
5

Because you cannot modify a TextNode, you can instead get all the parentNodes of that field, and call the put operation on it with the same field name and a new value. It will replace the existing field and change the value.

List<JsonNode> parentNodes = jsonNode.findParents("fieldName");
if(parentNodes != null) {
  for(JsonNode parentNode : parentNodes){
    ((ObjectNode)parentNode).put("fieldName", "newValue");
  }
}
  • 2
    It's always better to add an explanation to the code you're posting as an answer, so that it will helps visitors understand why this is a good answer. – abarisone Jul 12 '16 at 11:46
  • 1
    @abarisone - Because the code was self explanatory, I did not put an explanation. I have put it now, please check if it looks good. – Harshad Vyawahare Jul 13 '16 at 08:36