You can use elements() method and check if value key exist then add the value to list.
Smaple code
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(data);
List<String> values = new ArrayList<>();
jsonNode.forEach(jsonObject -> jsonObject.elements().forEachRemaining(valueNode -> {
if(valueNode.has("value"))
values.add(valueNode.get("value").asText());
}));
System.out.println(values);
Output:
[http://www.wikidata.org/entity/Q42442324, http://www.wikidata.org/prop/direct/P21, Kiisu Miisu, http://www.wikidata.org/entity/Q43260736, http://www.wikidata.org/prop/direct/P21, Paddles]
Answer from deadshot on Stack OverflowYou can use elements() method and check if value key exist then add the value to list.
Smaple code
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(data);
List<String> values = new ArrayList<>();
jsonNode.forEach(jsonObject -> jsonObject.elements().forEachRemaining(valueNode -> {
if(valueNode.has("value"))
values.add(valueNode.get("value").asText());
}));
System.out.println(values);
Output:
[http://www.wikidata.org/entity/Q42442324, http://www.wikidata.org/prop/direct/P21, Kiisu Miisu, http://www.wikidata.org/entity/Q43260736, http://www.wikidata.org/prop/direct/P21, Paddles]
Here is the solution by "Josson & Jossons". I list 2 more examples with condition filtering.
https://github.com/octomix/josson
implementation 'com.octomix.josson:josson:1.3.22'
---------------------------------------------
Josson josson = Josson.fromJsonString(
"[" +
" {" +
" \"item\": {" +
" \"type\": \"uri\", \"value\": \"http://www.wikidata.org/entity/Q42442324\"" +
" }," +
" \"prop\": {" +
" \"type\": \"uri\", \"value\": \"http://www.wikidata.org/prop/direct/P21\"" +
" }," +
" \"itemLabel\": {" +
" \"xml:lang\": \"en\", \"type\": \"literal\", \"value\": \"Kiisu Miisu\"" +
" }" +
" }," +
" {" +
" \"item\": {" +
" \"type\": \"uri\", \"value\": \"http://www.wikidata.org/entity/Q43260736\"" +
" }," +
" \"prop\": {" +
" \"type\": \"uri\", \"value\": \"http://www.wikidata.org/prop/direct/P21\"" +
" }," +
" \"itemLabel\": {" +
" \"xml:lang\": \"en\", \"type\": \"literal\", \"value\": \"Paddles\"" +
" }" +
" }" +
"]");
JsonNode node = josson.getNode("*.value");
System.out.println("1.\n" + node.toPrettyString());
node = josson.getNode("~'^item.*'.value");
System.out.println("2.\n" + node.toPrettyString());
node = josson.getNode("*[value.type='uri']*.value");
System.out.println("3.\n" + node.toPrettyString());
Output:
1.
[ "http://www.wikidata.org/entity/Q42442324", "http://www.wikidata.org/prop/direct/P21", "Kiisu Miisu", "http://www.wikidata.org/entity/Q43260736", "http://www.wikidata.org/prop/direct/P21", "Paddles" ]
2.
[ "http://www.wikidata.org/entity/Q42442324", "Kiisu Miisu", "http://www.wikidata.org/entity/Q43260736", "Paddles" ]
3.
[ "http://www.wikidata.org/entity/Q42442324", "http://www.wikidata.org/prop/direct/P21", "http://www.wikidata.org/entity/Q43260736", "http://www.wikidata.org/prop/direct/P21" ]
JSON Node to a Key/Value
How to iterate through all keys of json node
Get all the keys in a JSON string JsonNode in java - Stack Overflow
java - check if a jsonNode contains a specific key then EXTRACT its value once it exists - Stack Overflow
forEach will iterate over children of a JsonNode (converted to String when printed) and fieldNames() gets an Iterator<String> over keys. Here are some examples for printing elements of the example JSON:
JsonNode rootNode = mapper.readTree(option);
System.out.println("\nchoices:");
rootNode.path("choices").forEach(System.out::println);
System.out.println("\nAllKeys:");
rootNode.fieldNames().forEachRemaining(System.out::println);
System.out.println("\nChoiceSettings:");
rootNode.path("choiceSettings").fieldNames().forEachRemaining(System.out::println);
You'll probably need fields() at some point that returns an Iterator<Entry<String, JsonNode>> so you can iterate over key, value pairs.
This should do it.
Map<String, Object> treeMap = mapper.readValue(json, Map.class);
List<String> keys = Lists.newArrayList();
List<String> result = findKeys(treeMap, keys);
System.out.println(result);
private List<String> findKeys(Map<String, Object> treeMap , List<String> keys) {
treeMap.forEach((key, value) -> {
if (value instanceof LinkedHashMap) {
Map<String, Object> map = (LinkedHashMap) value;
findKeys(map, keys);
}
keys.add(key);
});
return keys;
}
This will print out result as
[required, requiredMsg, choices, exc, a, b, c, required, textbox, d, choiceSettings, type, Settings]
If you're trying to find a key which is placed inside nested object, you may use
findValue(String key) method which returns null if a value is not found by the given key:
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode= mapper.readTree(json);
String[] keys = {
"id", "create_date", "versions_control_advanced", "name", "nofield"
};
for (String key : keys) {
JsonNode value = rootNode.findValue(key);
System.out.printf("Key %s exists? %s --> value=%s%n", key, value != null,
value == null ? null : value.asText());
}
Output:
Key id exists? true --> value=276625
Key create_date exists? true --> value=2020-06-22T16:19:07
Key versions_control_advanced exists? true --> value=false
Key name exists? true --> value=
Key nofield exists? false --> value=null
I think you are not bound to the has() method.
You can convert the json to a map and then find the node recursively
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue( body, Map.class );
ArrayList<Object> container = new ArrayList<>();
boolean value = find( map, "id", container );
if( value )
{
System.out.println( container );
}
The recursive method should visit all the nodes and return soon as node is found
private static boolean find( Map<String, Object> map, String search, ArrayList<Object> container )
{
int i = 0;
for( String s : map.keySet() )
{
i++;
if( s.equals( search ) )
{
container.add( map.get( s ) );
return true;
}
if( map.get( s ) instanceof Map )
{
boolean found = find( (Map<String, Object>) map.get( s ), search, container );
if( i == map.size() || found )
{
return found;
}
}
}
return false;
}
I have edited the code to get the value also. hope this helps. I strongly suggest you to do more research on yourself before looking for help from the community.
With Jackson's tree model (JsonNode), you have both "literal" accessor methods (get), which returns null for missing value, and "safe" accessors (path), which allow you to traverse "missing" nodes. So, for example:
JsonNode root = mapper.readTree(inputSource);
int h = root.path("response").path("history").getValueAsInt();
which would return the value at the given path, or, if the path is missing, 0 (default value).
But more conveniently, you can just use JSON pointer expression:
int h = root.at("/response/history").getValueAsInt();
There are other ways too, and often it is more convenient to model your structure as a Plain Old Java Object (POJO). Your content could fit something like:
public class Wrapper {
public Response response;
}
public class Response {
public Map<String,Integer> features; // or maybe Map<String,Object>
public List<HistoryItem> history;
}
public class HistoryItem {
public MyDate date; // or just Map<String,String>
// ... and so forth
}
and if so, you would traverse the resulting objects just like any Java object.
Use Jsonpath
Integer h = JsonPath.parse(json).read("$.response.repository.history", Integer.class);