What you are trying to do is also called as Xpath in technical terms. It is used for html, xml based languages as well as now available in json
You can try jsonpath for this case:
https://www.baeldung.com/guide-to-jayway-jsonpath https://github.com/json-path/JsonPath
Answer from swapyonubuntu on Stack OverflowWhat you are trying to do is also called as Xpath in technical terms. It is used for html, xml based languages as well as now available in json
You can try jsonpath for this case:
https://www.baeldung.com/guide-to-jayway-jsonpath https://github.com/json-path/JsonPath
Google's popular GSON library has a method, namely getPath, maybe useful for your purpose:
String json = "...";
JsonReader reader = new JsonReader(new StringReader(json));
System.out.println(reader.getPath());
Java JsonPath API found at jayway JsonPath might have changed a little since all the above answers/comments. Documentation too. Just follow the above link and read that README.md, it contains some very clear usage documentation IMO.
Basically, as of current latest version 2.2.0 of the library, there are a few different ways of achieving what's been requested here, such as:
Pattern:
--------
String json = "{...your JSON here...}";
String jsonPathExpression = "$...your jsonPath expression here...";
J requestedClass = JsonPath.parse(json).read(jsonPathExpression, YouRequestedClass.class);
Example:
--------
// For better readability: {"store": { "books": [ {"author": "Stephen King", "title": "IT"}, {"author": "Agatha Christie", "title": "The ABC Murders"} ] } }
String json = "{\"store\": { \"books\": [ {\"author\": \"Stephen King\", \"title\": \"IT\"}, {\"author\": \"Agatha Christie\", \"title\": \"The ABC Murders\"} ] } }";
String jsonPathExpression = "$.store.books[?(@.title=='IT')]";
JsonNode jsonNode = JsonPath.parse(json).read(jsonPathExpression, JsonNode.class);
And for reference, calling 'JsonPath.parse(..)' will return an object of class 'JsonContent' implementing some interfaces such as 'ReadContext', which contains several different 'read(..)' operations, such as the one demonstrated above:
/**
* Reads the given path from this context
*
* @param path path to apply
* @param type expected return type (will try to map)
* @param <T>
* @return result
*/
<T> T read(JsonPath path, Class<T> type);
Hope this help anyone.
There definitely exists a way to query Json and get Json back using JsonPath. See example below:
String jsonString = "{\"delivery_codes\": [{\"postal_code\": {\"district\": \"Ghaziabad\", \"pin\": 201001, \"pre_paid\": \"Y\", \"cash\": \"Y\", \"pickup\": \"Y\", \"repl\": \"N\", \"cod\": \"Y\", \"is_oda\": \"N\", \"sort_code\": \"GB\", \"state_code\": \"UP\"}}]}";
String jsonExp = "$.delivery_codes";
JsonNode pincodes = JsonPath.read(jsonExp, jsonString, JsonNode.class);
System.out.println("pincodesJson : "+pincodes);
The output of the above will be inner Json.
[{"postal_code":{"district":"Ghaziabad","pin":201001,"pre_paid":"Y","cash":"Y","pickup":"Y","repl":"N","cod":"Y","is_oda":"N","sort_code":"GB","state_code":"UP"}}]
Now each individual name/value pairs can be parsed by iterating the List (JsonNode) we got above.
for(int i = 0; i< pincodes.size();i++){
JsonNode node = pincodes.get(i);
String pin = JsonPath.read("$.postal_code.pin", node, String.class);
String district = JsonPath.read("$.postal_code.district", node, String.class);
System.out.println("pin :: " + pin + " district :: " + district );
}
The output will be:
pin :: 201001 district :: Ghaziabad
Depending upon the Json you are trying to parse, you can decide whether to fetch a List or just a single String/Long value.
Hope it helps in solving your problem.
String json = "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"address\":{\"street\":"
+ "\"21 2nd Street\",\"city\":\"New York\",\"postalCode\":\"10021-3100\","
+ "\"coordinates\":{\"latitude\":40.7250387,\"longitude\":-73.9932568}}}";
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(json);
JsonNode coordinatesNode = node.at("/address/coordinates");
This is a JSON Pointer approach which I found here: https://cassiomolin.com/2016/07/13/using-jackson-and-json-pointer-to-query-and-parse-an-arbitrary-json-node/
The Jayway JsonPath library has support for reading values using a JSON path.
For example:
String json = "...";
Map<String, Object> book = JsonPath.read(json, "$.store.book[0]");
System.out.println(book); // prints {category=reference, author=Nigel Rees, title=Sayings of the Century, price=8.95}
Double price = JsonPath.read(json, "$.store.bicycle.price");
System.out.println(price); // prints 19.95
You can also map JSON objects directly to classes, like in GSON or Jackson:
Book book = JsonPath.parse(json).read("$.store.book[0]", Book.class);
System.out.println(book); // prints Book{category='reference', author='Nigel Rees', title='Sayings of the Century', price=8.95}
If you would like to specifically use GSON or Jackson to do the deserialization (the default is to use json-smart), you can also configure this:
Configuration.setDefaults(new Configuration.Defaults() {
private final JsonProvider jsonProvider = new JacksonJsonProvider();
private final MappingProvider mappingProvider = new JacksonMappingProvider();
@Override
public JsonProvider jsonProvider() {
return jsonProvider;
}
@Override
public MappingProvider mappingProvider() {
return mappingProvider;
}
@Override
public Set<Option> options() {
return EnumSet.noneOf(Option.class);
}
});
See the documentation for more details.
Using the path is currently (.NET 7) not supported. It might be supported in a later version.
From documentation:
The JsonDocument DOM doesn't support querying by using JSON Path.
In a JsonNode DOM, each JsonNode instance has a GetPath method that returns a path to that node. But there is no built-in API to handle queries based on JSON Path query strings.
If you need very flexible Json support, use the Newtonsoft.Json Nuget package.
Although this is an old post, this came top in Google search. This is how I implemented using path;
extension method to JsonNode
private static JsonNode GetNodeUsingPath(this JsonNode root, string path)
{
if (root == null || string.IsNullOrEmpty(path))
return null;
string[] parts = path.Split('.', StringSplitOptions.RemoveEmptyEntries);
JsonNode currentNode = root;
// ignore 0th element as it is for root $
for (int x = 1; x < parts.Length; x++)
{
if (currentNode == null)
return null;
currentNode = currentNode[parts[x]];
}
return currentNode;
}
usage;
string path = "$.cakes.cheese";
JsonNode cheeseNode = rootNode.GetNodeUsingPath(path);