javydreamercsw
javydreamercsw

Reputation: 5099

JSON: Parse ArrayNode of Arrays

I'm trying to parse a JSON ArrayNode in Java but I'm having some issues.

The object is as follows:

{
  "type": "type",
  "id": "id",
  "attributes": {
    "x": [ "x.value" ],
    "y": [ "y.value" ],
    "z": [ "z.value" ]
  }
}

I'm parsing it as follows:

Map<String, Map<String, String>> users = new HashMap<>();
Iterator<JsonNode> arrayIterator = dataArray.elements();
while (arrayIterator.hasNext())
{
  JsonNode r = arrayIterator.next();
  String id = r.get("id").asText();
  users.put(id, new HashMap<>());
  Iterator<JsonNode> attributeIterator = r.path("attributes").elements();
  while (attributeIterator.hasNext())
  {
    JsonNode attribute = attributeIterator.next();
    users.get(id).put(attribute.asText(),
            attribute.elements().next().asText());
  }
}

But I'm getting a map like this:

"" => z.value

I found out in Java' documentation that the attribute .asText() will return empty if it is not a value node. How can I get that name so my map is instead:

x => x.value
y => y.value
z => z.value

Upvotes: 0

Views: 1213

Answers (1)

Gatusko
Gatusko

Reputation: 2598

Well the first thing you need the keys of your JSON. So I tried with fields instead of only elements

  Iterator<Map.Entry<String, JsonNode>> attributeIterator = dataArray.path("attributes").fields();
            while (attributeIterator.hasNext())
            {
                Map.Entry<String, JsonNode> attribute = attributeIterator.next();
                users.get(id).put(attribute.getKey(),
                        attribute.getValue().get(0).asText());
            }

I didn't like to get an array So I change to this

Iterator<Map.Entry<String, JsonNode>> attributeIterator = dataArray.path("attributes").fields();
            while (attributeIterator.hasNext())
            {
                Map.Entry<String, JsonNode> attribute = attributeIterator.next();
                users.get(id).put(attribute.getKey(),
                        attribute.getValue().elements().next().textValue());
            }

The reason I used fields because I needed the key value :

Iterator that can be used to traverse all key/value pairs for object nodes; empty iterator (no contents) for other types

And elements doesn't include keys:

Method for accessing all value nodes of this Node, iff this node is a JSON Array or Object node. In case of Object node, field names (keys) are not included, only values. For other types of nodes, returns empty iterator.

From Java Docs

This is getting the map filled. I used jackson 2.9.4

Upvotes: 1

Related Questions