Search code examples
javajacksondeserializationrest-assured

How to traverse/iterate JsonNode to find parents of particular node


I am trying to create custom deserializator of some REST response. This is example of returned object:

"someField": [
        {
            "key": "foo",
            "value": {
                "left": "bar_left",
                "right": "bar_right"
            }
        },

        {
            "key": "foo2",
            "value": {
                "left": "bar_left2",
                "right": "bar_right2"
            }
        }
    ],
"anotherField: [
        {
            "key": "foo3",
            "value": {
                "left": "bar_left",
                "right": "bar_right"
            }
        },

        {
            "key": "foo4",
            "value": {
                "left": "bar_left2",
                "right": "bar_right2"
            }
        }
    ],
"someMoreField": {}

What I am trying to achieve is retrieval of left and right value based on given key (which is unique).

So far I got something like that:

List<JsonNode> keys = rootNode.findValues("key");

for (JsonNode keyNode: keys ) {
    if (keyNode.asText().equals("foo")) {
        System.out.println("NODE FOUND!");
        //and here I would like to go one node up:
        JsonNode parent = keyNode.getParent(); //such method doesn't exist
        System.out.println(parent.get("left"));
    }
}

Because JsonNode is one-way linked there is no possibility to access parent node.

Does someone of you know how could I efficiently iterate/parse JsonNode throw all levels so I could compare key value while keeping reference to the parent?

I have something like that on my mind:

JsonNode rootNode = //some retrieval blablalbal
JsonNode parent = rootNode;
Iterator<JsonNode> it = rootNode.iterateAllLevels()
while (it.hasNext()) {
    JsonNode current = it.next();
    if(current.asText().equals("searched key")) {
         parent.get("value");
    }
    parent = current;
}

Maybe there is some other way to achieve that?


Solution

  • In order to extract few values from a really complex object, you need to use JSON Path. I don't know if you use it in your project, but this is definitely the right tool for your problem. It simply helps you locate your elements based on your criteria. You write down your query and it finds your elements

    Information about the lib (installation, set up) is found here. It is very simple to use.

    Based on your JSON structure, to find your left and right, you can use the following path

    • left : $..[?(@.key=='myFooValue')].value.left
    • right: $..[?(@.key=='myFooValue')].value.rigth

    with myFooValue being the value of your input key.

    Hope it helps.