Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson -- parse json using xpath or similar

I have some json and it's fairly complex -- (a bit too complex and open-ended to model using something like gson), and I need to extract string values from certain nodes into a list of strings.

The following code works, but due to the way my json works -- it's grabbing lots of extra stuff that I don't want (note: I don't own the json schema)

ObjectMapper mapper = new ObjectMapper();
        JsonNode node = mapper.readTree(json);
        List<JsonNode> keys = node.findValues("key") ;
for(JsonNode key: keys){
         System.out.println(key.toString());
}

The contents of Json is fairly complex (Jira filter export) which looks like this:

{
    "issues": [
    {
        "key":"MIN-123",
        ...
        "fields":{
             "key":"A_Elric"
        }
    }
    ]
}

Assertions: I always want to extract issues[x].key and not any of the subkeys. I would prefer to extract this into a list, but any normal data structure is fine. I'm already using Jackson -- but gson is also an option if there's a sane way of doing so.

Thanks for the assist!

like image 391
A_Elric Avatar asked Oct 26 '25 11:10

A_Elric


2 Answers

JsonPath is xpath for json, and it has a Java implementation. Here is a working example to get issue keys without subkeys:

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class JsonPathTest {

    public static String ROOT_ARRAY = "issues";
    public static String KEY = "key";
    // get all KEYs right under ROOT array
    public static String jsonPath = String.format("$.%s[*].%s", ROOT_ARRAY, KEY);

    public static void main(String[] args) {
        try {
            String jsonStr = new String(Files.readAllBytes(Paths.get("c:/temp/xx.json")));
            Object jsonObj = Configuration.defaultConfiguration().jsonProvider().parse(jsonStr);
            List<String> keys = JsonPath.parse(jsonObj).read(jsonPath);
            System.out.println(keys);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
like image 162
Sharon Ben Asher Avatar answered Oct 29 '25 01:10

Sharon Ben Asher


Check Jackson at and jsonPointer here jackson.core, I'm ussing something like:

JsonNode input = objectMapper.readTree(fileStream);

String device_name = input.at("/device/name").asText();

JsonNode fq_name_list = input.at("/abstract_config/fq_name");
if (fq_name_list.isMissingNode()) continue;

String fq_name = fq_name_list.get(fq_name_list.size() - 1).asText();
logger.info(" device:{} abstract_config:{}",device_name,fq_name);
like image 22
José Ibañez Avatar answered Oct 29 '25 03:10

José Ibañez