如何从 JSON 字符串中递归删除某些具有指定名称的字段?
例如,我想从以下 JSON 中删除“firstName”字段:
输入:
{
"name" : "abc",
"secondName": "qwe",
"add" : "abcd",
"moreDetails" : {
"secondName": "qwe",
"age" : "099"
}
}
输出:
{
"name" : "abc",
"add" : "abcd",
"moreDetails" : {
"age" : "099"
}
}
我必须从具有不同结构/模式的许多不同 JSON 中删除一些字段,因此我将无法对 POJO 进行反序列化/序列化。
如果您知道架构和层次结构,您可以执行以下操作:
JsonObject jsonObj= gson.fromJson(json, JsonObject.class);
jsonObj.getAsJsonObject("moreDetails").remove("secondName");
System.out.println(jsonObj.getAsString());
请参阅此处以获取更多信息从 JsonObject 内的 Json 中删除密钥
否则你需要编写一个动态函数,它将检查 JSON 对象的每个元素,并尝试找到其中的
secondName
元素并将其删除。
因此,请考虑这里,因为您有多个嵌套对象,那么您需要编写一个函数,该函数将迭代每个元素并检查其类型,如果它再次是 jsonObject 递归或迭代地调用相同的方法来检查当前元素,在每次检查中您需要还要验证密钥,如果它与必须删除的密钥匹配,那么您可以删除它并继续相同的操作。
有关如何检查 JSON 值类型的提示,请参阅此 如何检查 JSONObject 中的值类型?
Gson 将任何有效的 Json 反序列化为
LinkedTreeMap
,例如:
LinkedTreeMap<?,?> ltm = new Gson().fromJson(YOUR_JSON, LinkedTreeMap.class);
然后就是制作一些递归方法来进行清理:
public void alterEntry(Entry<?, ?> e) {
if(e.getValue() instanceof Map) {
alterMap((Map<?, ?>) e.getValue());
} else {
if(e.getKey().equals("secondName")) { // hard coded but you see the point
e.setValue(null); // we could remove the whole entry from the map
// but it makes thing more complicated. Setting null
// achieves the same.
}
}
}
public void alterMap(Map<?,?> map) {
map.entrySet().forEach(this::alterEntry);
}
用途:
alterMap(ltm);
您可以尝试将 JSON 存储为
JSONObject
,使用 jsonObject.names()
迭代键并使用 jsonObject.remove(key)
删除条目。
您可以使用 Jackson 中的
JsonNode.findParents(String fieldName)
方法轻松完成此操作。然后在每个父对象上调用 ObjectNode.remove(String propertyName)
。最后,您将得到一个 JsonNode,其中所有具有给定字段名称的字段都被删除。
String input = """
{
"name" : "abc",
"secondName": "qwe",
"add" : "abcd",
"moreDetails" : {
"secondName": "qwe",
"age" : "099"
}
}
""";
JsonNode baseNode = new JsonMapper().readTree(input);
List<JsonNode> parents = baseNode.findParents("secondName");
for (JsonNode parent : parents) {
((ObjectNode) parent).remove("secondName");
}