Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find a node by name in a Json Tree?

Tags:

java

json

jackson

I am doing inverse geocoding using google geocoding APIs.

The results are returned in Json which I'm parsing in following manner -

Map<String, Object> parsedJson = new ObjectMapper().readValue(
                    response.getEntity(String.class),
                    new TypeReference<Map<String, Object>>() {
                    });
List<Object> results = (List<Object>) parsedJson.get("results");
// From first result get geometry details
Map<String, Object> geometry = (Map<String, Object>) ((Map<String, Object>) results
                    .get(0)).get("geometry");

Map<String, Object> location = (Map<String, Object>) geometry
                    .get("location");

Map<String, Double> coordinates = new HashMap<String, Double>();
coordinates.put("latitude", (Double) location.get("lat"));
coordinates.put("longitude", (Double) location.get("lng"));

Where response contains the Json returned from server.

Is it possible to get a direct reference to the location node without going through all this? E.g. is there something like -

new ObjectMapper().readValue(json).findNodeByName("lat").getFloatValue();

I have read the docs on JsonNode and Tree in Jackson Api but it seems they are useful only if you want to traverse the entire tree.

What would be the easiest way to fetch only a particular node?

like image 683
Kshitiz Sharma Avatar asked Apr 25 '12 14:04

Kshitiz Sharma


People also ask

How do you Recognise a node in JSON?

You could use the String method "contains()", which will return true if the string contains the specified substring. Or, you could use JSON. deserialize() to create a collection of objects and then see if the object you want exists, and what values it has.

How do I traverse JSON data in JavaScript?

Use the JavaScript function JSON.parse() to convert text into a JavaScript object: const obj = JSON.parse('{"name":"John", "age":30, "city":"New York"}'); Make sure the text is in JSON format, or else you will get a syntax error.

What is a node JSON?

JavaScript Object Notation, or JSON, is a lightweight data format that has become the defacto standard for the web. JSON can be represented as either a list of values, e.g. an Array, or a hash of properties and values, e.g. an Object.


2 Answers

+1 to Michael Hixson for pointing out the geocoding library.

But, after digging through the docs I've finally found the solution -

ObjectMapper mapper = new ObjectMapper(); 

JsonNode rootNode = mapper.readTree(mapper.getJsonFactory()
                        .createJsonParser(response.getEntity(String.class)));

rootNode.findValue("lat").getDoubleValue();
like image 56
Kshitiz Sharma Avatar answered Nov 15 '22 08:11

Kshitiz Sharma


I don't have an answer to your "how to find a node by name" question, but if you're just looking for a cleaner way of reading this data, then I'd recommend one of these approaches, in order:

A: Look for a pre-existing Java library for Google's Geocoding API. If right now you're making HTTP requests for this data in Java (using Apache HttpClient or something) and then parsing the JSON with Jackson, someone has probably done all that work before and packaged it up in a library. A quick search brought up this: http://code.google.com/p/geocoder-java/. You could get the first latitude value like this:

GeocodeResponse response = ... // Look at the example code on that site.
BigDecimal latitude = response.getResults().get(0).getGeometry().getLocation().getLat()

B: Create your own class hierarchy to represent the stuff you need, and then given Jackson the JSON and your root "response" class. I'm pretty sure it can build up instances of arbitrary classes from JSON. So something like this:

public class ResultSet {
  public List<Result> results;
}

public class Result {
  public Geometry geometry;
}

public class Geometry {
  public Location location;
}

public class Location {
  public double latitude;
  public double longitude;
}

String json = ... // The raw JSON you currently have.
Response response = new ObjectMapper().readValue(json, Response.class);
double latitude = response.results.get(0).geometry.location.latitude;
like image 33
Michael Hixson Avatar answered Nov 15 '22 09:11

Michael Hixson