使用Jackson删除JSON元素

46

我有一个特定的JSON节点,对应于import org.codehaus.jackson.JsonNode而不是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"
    }
]

我想从上述数组的所有JSON节点中删除“familyName”和“middleName”。有没有办法实现这一点?

7个回答

55

我没有测试过这个,但是我认为像这样的东西会实现你想要的功能:

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

使用Jackson的原始解析API可以更有效率地完成此操作,但代码会比较混乱。


6

Jackson的ObjectMapper只需要几个步骤就可以解决。

将json数据保存在名为"data.json"的文件中。 复制以下代码到一个没有导入语句的函数中,并调用该函数。 生成的JSON将被写入一个新文件"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);

1
你也可以使用 ((ObjectNode)node).remove(Collection<String>),例如 ((ObjectNode)node).remove(Arrays.asList("familyName","middleName")); - Superpaul

2

我最近遇到了这个问题,因为我有一个不同寻常的JSON片段需要删除其中的一个元素:

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

前三个元素代表了一个人和相应的分数对象。最后一个元素"warnings"与分数对象不匹配,我想要将其删除。

以gsteff的答案中的rootNode作为起始Json节点,我发现可以通过迭代每个节点,将节点的映射对象添加到HashMap中,这是我想要的返回对象,除非它是"warnings"元素:

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;

1

根据JSONObject文档的说明, JSONObject实现了Map.remove,该方法返回存储在该键上的值。使用它的方式如下:

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

3
这与Json对象不同,是关于Json节点的。 - Alexander Volkov

1
写的答案也可以使用,但我认为更简单的方法是使用对象映射器将其转换为JSONArray,而不是JsonNode,然后从那里开始。
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);
        }

1
我不明白那有什么更容易的方法。 - eis

0
我需要的是从扁平根对象中删除具有特定前缀键的元素。我的解决方案是这样的:
Iterator<String> it = jsonNode.fieldNames();
        while (it.hasNext()) {
            String nextKey = it.next();
            if (nextKey.startsWith("prefix")) {
                it.remove();
                ((ObjectNode)jsonNode).remove(nextKey);
            }
        }

请记住,您还必须从迭代器中删除元素,否则您将会得到ConcurrentAccess类型的异常。


-4
你可以创建一个新的JSONObject,读取除了“familyName”和“middleName”之外的所有节点,然后将它们保存到一个新文件中。 这里有一个例子。JSON.Simple Example – Read And Write JSON

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接