java - 如何使用 Jackson 从 Json 文件中删除文本节点
问题描述
我正在尝试使用 Jackson api 从 Json 中删除文本节点,但出现以下错误:
com.fasterxml.jackson.databind.node.TextNode cannot be cast to com.fasterxml.jackson.databind.node.ObjectNode
不知道我哪里出错了。
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readValue(jsonText, JsonNode.class);
for (JsonNode node : json) {
if (node.isNull() || node.isBoolean() || node.isNumber() || node.isTextual()) {
((ObjectNode) node).removeAll();
}
}
我明白了为什么我会来到这里 bcz 我正在尝试将原语转换为对象,如何从 Json 中删除原语节点,我需要在这里做什么。
解决方案
这里的问题不是因为原语与对象,而是因为 anObjectNode
代表一个 JSON 对象——即一个{...}
结构,而 aTextNode
代表一段 JSON 文本"foo"
。您无法在代表这些不同 JSON 结构的这些不同 Java 对象之间进行转换。
要删除 JSON 结构的部分,我建议使用迭代器。
假设我们有一些测试数据:
{
"count": 123,
"active": true,
"message": "hello world",
"details": {
"firstName": "John",
"lastName": "Smith"
}
}
我将在以下代码示例中将其作为字符串处理:
String jsonText = "{\"count\":123,\"active\":true,\"message\":\"hello world\",\"details\":{\"firstName\":\"John\",\"lastName\":\"Smith\"}}";
System.out.println(jsonText);
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readValue(jsonText, JsonNode.class);
Iterator<JsonNode> it = json.iterator();
while (it.hasNext()) {
JsonNode node = it.next();
if (node.isNull() || node.isBoolean() || node.isNumber() || node.isTextual()) {
it.remove();
}
}
String outputText = mapper.writeValueAsString(json);
System.out.println(outputText);
输出如下:
{"count":123,"active":true,"message":"hello world","details":{"firstName":"John","lastName":"Smith"}}
{"details":{"firstName":"John","lastName":"Smith"}}
所有文本、布尔值和数字字段都已被删除 - 只有“详细信息”对象{...}
没有被删除。如果测试输入包含一个数组[...]
,那也将被保留。
请注意,此解决方案仅迭代 JSON 测试数据中的顶级节点。它不会遍历“详细信息”数组中的子节点。如果您想深入了解 JSON 的层次结构,则需要修改方法 - 例如通过递归调用方法:
private JsonNode removeUnwantedNodes(JsonNode json) {
Iterator<JsonNode> it = json.iterator();
while (it.hasNext()) {
JsonNode node = it.next();
if (node.isNull() || node.isBoolean() || node.isNumber() || node.isTextual()) {
it.remove();
} else if (node.isContainerNode()) {
removeUnwantedNodes(node);
}
}
return json;
}
在此示例中,该isContainerNode()
方法检查 JSON 对象{...}
和 JSON 数组[...]
。
更新 - 空容器
删除 text/boolean/number 节点的一个后果是您的 JSON:{}
和[]
.
您可能需要一个或多个后续通行证才能删除这些通行证。
检查的条件是:
if (node.isContainerNode() && node.isEmpty()) {
it.remove();
}
这可以添加到上面显示的方法中。
我的处理方式如下:
(a) 在对其进行迭代之前创建 JSON 的深层副本(用于删除节点)。使用 制作副本JsonNode prevJson = json.deepCopy();
。
(b) 使用while
循环重复迭代 JSON,将生成的 JSON 与之前的副本进行比较:
while (!json.equals(prevJson)) {
prevJson = json.deepCopy();
json = iterateForRemoval(json);
}
一旦删除过程不再找到需要删除的任何内容,您就完成了。
这对于清理诸如嵌套数组和对象之类的东西是必要的[ [ [...] ] ]
,其中第一次传递只能清理最里面的数组,随后的传递将删除生成的空数组。
推荐阅读
- javascript - Ajax 回调成功:function() 不起作用
- java - 在as400框内执行时如何判断Java代码正在执行的库列表(rpgle程序调用)
- google-chrome - Chrome 在 Ant Media Server 中发布 WebRTC 流时给出“NotSupportedError”
- kubernetes - Does Istio really can't perform filter HTTPS requests based on the destination domains?
- swift - How To Get Time of Video Playback When User Closes AVPlayer
- c# - 如何在 LibUsbDotNet 的 UsbDeviceFinder 函数中使用我设备的 VID 和 PID?
- python - _pickle.UnpicklingError:无效的加载键,'D'
- java - How to access Twitter API resources using Twitter's Java library (twitter4j)
- java - SAML 响应未到达 SuccessHandler
- java - How to use List with JDL entities in Jhipster