oikonomiyaki
oikonomiyaki

Reputation: 7951

Filtering Jackson's JsonNode element based on attribute values

I'm parsing a json using Jackson's JsonNode. My json structure looks like this (let this be variable rawJson):

{
    <some fields...>,
    "results" : [
            {
                "name" : "name1",
                "data" : ...,
                "values" : 13
            }, 
            {
                "name" : "name2",
                "data" : ...,
                "values" : 20
            },
            .
            .
            .
            {
                "name" : "name_n",
                "data" : ...,
                "values" : 151
            }
        ]
}

in Java:

ObjectMapper mapper = new ObjectMapper();
JsonNode results = mapper.readValue(rawJson, JsonNode.class).get("results");

How can I get the particular JsonNode element by filtering the attribute name? How about if I want to get JsonNode elements whose value greater than X? Can I accomplish these without looping through the results variable?

Upvotes: 4

Views: 6490

Answers (1)

Mohit
Mohit

Reputation: 1755

You can use forEach(Consumer c) (JDK 1.8+) function of java.lang.Iterable to perform list iteration. This method takes a Consumer instance which process all the values in the list. This approach can be extended to take a filter while iterating as shown below:

public static void main(String[] args) {

    ObjectMapper om = new ObjectMapper();
    InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("test.json");
    try {
        JsonNode node = om.readValue(in, JsonNode.class).get("results");
        NodeFilteringConsumer consumer = new NodeFilteringConsumer(new NodeFilter() {

            @Override
            public boolean apply(JsonNode node) {
                //Filter for node with values greater than 20.
                return node.get("values").asDouble() > 20;
            }
        });

        node.forEach(consumer);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static interface NodeFilter{

    boolean apply(JsonNode node);
}

public static class NodeFilteringConsumer implements Consumer<JsonNode>{

    private NodeFilter f;

    public NodeFilteringConsumer(NodeFilter f) {
        this.f = f;
    }


    @Override
    public void accept(JsonNode t) {
        if (f.apply(t)){
            //Only filtered records reach here
            System.out.println("Filter applied on node:" + t);
        }
    }

}

Upvotes: 3

Related Questions