altz
altz

Reputation: 23

Getting the values of a specific key from JsonNode

I have a JsonNode result represented as:

[
  {
    "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"
    }
  }
]

I am trying to retieve the values of the key "value" into an array list using the below code but am getting the error Cannot invoke "com.fasterxml.jackson.databind.JsonNode.findValue(String)" because the return value of "com.fasterxml.jackson.databind.JsonNode.get(int)" is null

for (int i = 0; i < resultSize; i++) {
    JsonNode jsonObject = results.get(i);
    if (indexRow < jsonObject.size()) {
        jsonRows = Collections.singletonList(jsonObject.get(indexRow++).findValue("value").asText());
    }
}

The value of variable jsonObject in the first iteration from the debugger is

{
  "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"
  }
}

Expected output is

[
  "http://www.wikidata.org/entity/Q42442324",
  "http://www.wikidata.org/entity/Q42442324",
  "Kiisu Miisu",
  "http://www.wikidata.org/entity/Q43260736",
  "http://www.wikidata.org/prop/direct/P21",
  "Paddles"
]

Upvotes: 1

Views: 8367

Answers (2)

Raymond Choi
Raymond Choi

Reputation: 1273

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" ]

Upvotes: 0

deadshot
deadshot

Reputation: 9061

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]

Upvotes: 2

Related Questions