首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Jackson从Json文件中删除文本节点

如何使用Jackson从Json文件中删除文本节点
EN

Stack Overflow用户
提问于 2020-08-25 12:41:48
回答 1查看 1.2K关注 0票数 1

我试图使用Jackson api从Json中删除一个文本节点,但下面是错误:

代码语言:javascript
运行
复制
com.fasterxml.jackson.databind.node.TextNode cannot be cast to com.fasterxml.jackson.databind.node.ObjectNode

不知道我哪里搞错了。

代码语言:javascript
运行
复制
    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();
    }
}

我明白了为什么我要到这里来,我试图把原语转换成对象,如何从Json删除一个原语节点,在这里我需要做什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-25 13:37:44

这里的问题不在于原语与对象之间的关系,而是因为ObjectNode表示一个JSON对象-即一个{...}结构,而一个TextNode代表一段JSON文本"foo"。您不能在表示这些不同JSON结构的不同Java对象之间进行转换。

要删除JSON结构的部分,我建议使用迭代器。

假设我们有一些测试数据:

代码语言:javascript
运行
复制
{
    "count": 123,
    "active": true,
    "message": "hello world",
    "details": {
        "firstName": "John",
        "lastName": "Smith"
    }
}

我将在以下代码示例中将其作为字符串处理:

代码语言:javascript
运行
复制
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);

这方面的产出如下:

代码语言:javascript
运行
复制
{"count":123,"active":true,"message":"hello world","details":{"firstName":"John","lastName":"Smith"}}
{"details":{"firstName":"John","lastName":"Smith"}}

所有文本、布尔值和数字字段都已被删除--只有“详细信息”对象{...}未被删除。如果测试输入包含一个数组[...],那么它也会被保留下来。

请注意,此解决方案仅在JSON测试数据中的顶级节点上迭代。它不对"details“数组中的子节点进行迭代。如果要深入研究JSON的层次结构,则需要修改方法--例如,递归调用方法:

代码语言:javascript
运行
复制
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数组[...]

更新-空容器

删除文本/布尔/数字节点的一个后果是,您可以在JSON中以空容器结束:{}[]

您可能需要一个或多个后续的通行证来删除这些。

检查的条件是:

代码语言:javascript
运行
复制
if (node.isContainerNode() && node.isEmpty()) {
    it.remove();
}

这可以添加到上面所示的方法中。

我处理这件事的方式如下:

(a)在迭代JSON之前创建JSON的深层副本(用于节点删除)。使用JsonNode prevJson = json.deepCopy();制作副本。

(b)使用while循环反复遍历JSON,并将得到的JSON与前面的副本进行比较:

代码语言:javascript
运行
复制
while (!json.equals(prevJson)) {
    prevJson = json.deepCopy();
    json = iterateForRemoval(json);
}

一旦移除过程找不到需要移除的任何内容,您就完成了。

这是清理嵌套数组和对象所必需的:[ [ [...] ] ],其中第一次传递只能清理最内部的数组,随后的传递将删除结果中的空数组。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63579097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档