46

I've a particular JSON Node that corresponds to import org.codehaus.jackson.JsonNode, and not import org.codehaus.jackson.map.JsonNode.

[
    {
        "givenName": "Jim",
        "formattedName": "jimJackson",
        "familyName": null,
        "middleName": "none",
        "honorificPrefix": "mr",
        "honorificSuffix": "none"
    },
    {
        "givenName": "john",
        "formattedName": "johnLasher",
        "familyName": null,
        "middleName": "none",
        "honorificPrefix": "mr",
        "honorificSuffix": "none"
    },
    {
        "givenName": "carlos",
        "formattedName": "carlosAddner",
        "familyName": null,
        "middleName": "none",
        "honorifiPrefix": "mr",
        "honorificSuffix": "none"
    },
    {
        "givenName": "lisa",
        "formattedName": "lisaRay",
        "familyName": null,
        "middleName": "none",
        "honorificPrefix": "mrs",
        "honorificSuffix": "none"
    },
    {
        "givenName": "bradshaw",
        "formattedName": "bradshawLion",
        "familyName": null,
        "middleName": "none",
        "honorificPrefix": "mr",
        "honorificSuffix": "none"
    },
    {
        "givenName": "phill",
        "formattedName": "phillKane",
        "familyName": null,
        "middleName": "none",
        "honorificPrefix": "mr",
        "honorificSuffix": "none"
    },
    {
        "givenName": "Gabriel",
        "formattedName": "gabrielMoosa",
        "familyName": null,
        "middleName": "none",
        "honorificPrefix": "mr",
        "honorificSuffix": "none"
    }
]

I want to remove the "familyName" and "middleName" from all the JSON nodes of the above array. Is there any way to achieve this?

ppasler
  • 3,579
  • 5
  • 31
  • 51
R Syed
  • 1,043
  • 5
  • 14
  • 22

7 Answers7

55

I haven't tested this, but I think something like this would do what you want:

import org.codehaus.jackson.node.ObjectNode;
// ...
for (JsonNode personNode : rootNode) {
    if (personNode instanceof ObjectNode) {
        ObjectNode object = (ObjectNode) personNode;
        object.remove("familyName");
        object.remove("middleName");
    }
}

You could also do this more efficiently using Jackon's raw parsing API, but the code would be a lot messier.

gsteff
  • 4,764
  • 1
  • 20
  • 17
6

ObjectMapper of Jackson gives solution with only few steps.

Save the json data in a file say 'data.json'. Copy following the code into a function without import statements and invoke the function. The resulting JSON will be written into a new file 'data1.json'.

import java.io.File;
import java.io.IOException;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(new File("data.json"));
        for (JsonNode node : jsonNode) {
            ((ObjectNode)node).remove("familyName");
            ((ObjectNode)node).remove("middleName");
        }
        objectMapper.writeValue(new File("data1.json"), jsonNode);
Nayana Shekar C
  • 111
  • 2
  • 6
  • 1
    you can also use `((ObjectNode)node).remove(Collection)` for example `((ObjectNode)node).remove(Arrays.asList("familyName","middleName"));` – Superpaul Aug 01 '18 at 11:11
2

I recently came to this question because I had an unusual piece of JSON that I needed to remove an element of:

{
   "allan": { "score": 88 },
   "bill": { "score": 75 },
   "cassie": { "score": 96 },
   "warnings": [ { "name": "class_low_numbers", "message": "this class is has less than 10 students" }]
}

The first three elements represent a person and a respective score object. The last one "warnings", didn't match the score object and that's the one I wanted to remove.

Taking the rootNode as the starting JsonNode from gsteff's answer above, the way I found to remove this was to iterate through each of the nodes, adding an object mapped version of the node to a HashMap which was the desired return object that I wanted unless it was the "warnings" element:

HashMap<String, ScoreDetails> results = new HashMap<String, ScoreDetails>();

ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Iterator<Map.Entry<String, JsonNode>> fields = rootNode.fields();
while (fields.hasNext()) {
  Map.Entry<String, JsonNode> next = fields.next();
  if (!next.getKey().equals("warnings")) {
    results.put(
        next.getKey(), mapper.treeToValue(next.getValue(), ScoreDetails.class));
  }
}

return results;
rusty
  • 31
  • 3
1

The answer written by gsteff can be used too, but I thought an easier way was to use the object mapper to convert to JSONArray instead of JsonNode and go from there.

ObjectMapper mapper = new ObjectMapper();
String stringJsonArray = mapper.writeValueAsString(list);
JSONArray csvDatabindedtoBean = new JSONArray(stringJsonArray);
        JSONArray finalArray = new JSONArray();
for (int val = 0; val < csvDatabindedtoBean.length(); val++) {
            JSONObject finalObject = csvDatabindedtoBean.getJSONObject(val);
                finalObject.remove("familyName");
                finalObject.remove("middleName");

            }
            finalArray.put(finalObject);
        }
R Syed
  • 1,043
  • 5
  • 14
  • 22
1

According to the JSONObject documentation, JSONObject implements Map.remove, which returns the value stored at that key. Use it like

JSONObject json = new JSONObject();
json.put("key", "value");
String str = (String)json.remove("key");
0

What I needed was to remove elements from flat root object that have keys with a specific prefix. My solution was this:

Iterator<String> it = jsonNode.fieldNames();
        while (it.hasNext()) {
            String nextKey = it.next();
            if (nextKey.startsWith("prefix")) {
                it.remove();
                ((ObjectNode)jsonNode).remove(nextKey);
            }
        }

Keep in mind you have to remove element from iterator as well, otherwise you will get a ConcurrentAccess type of Exception.

Cristian
  • 56
  • 4
-4

You can just create a new JSONObject, read all nodes except "familyName" and "middleName", then save them all to a new file. Here is an example. JSON.Simple Example – Read And Write JSON

Sifeng
  • 713
  • 9
  • 23