在对象节点树中删除具有空值的JSON对象

时间:2019-03-21 20:46:03

标签: java json jackson apache-camel

我有一个JSON文件,需要从其中删除包含数据值null的节点对象。能做到吗?我正在使用杰克逊。

在下面的示例JSON中,我需要删除其“ v”标记具有null值的对象。

示例:

{
  "tags" : [ {
    "tagId" : "G1.A_90LT1OUT",
    "data" : [ {
      "ts" : "2019-03-20T15:27:36",
      "v" : "96.2427826",
      "q" : "3"
    } ]
  }, {
    "tagId" : "G1.A_90WN1OUT",
    "data" : [ {
      "ts" : "2019-03-20T15:27:36",
      "v" : null,
      "q" : "0"
    } ]
  }, {
    "tagId" : "G1.A_90LT1OUT",
    "data" : [ {
      "ts" : "2019-03-20T15:29:20",
      "v" : "96.2427826",
      "q" : "3"
    } ]
  }, {
    "tagId" : "G1.A_90WN1OUT",
    "data" : [ {
      "ts" : "2019-03-20T15:29:20",
      "v" : null,
      "q" : "0"
    } ]
  }, {
    "tagId" : "G1.A_90LT1OUT",
    "data" : [ {
      "ts" : "2019-03-20T15:29:37",
      "v" : "96.2581177",
      "q" : "3"
    } ]
  }, {
    "tagId" : "G1.A_90WN1OUT",
    "data" : [ {
      "ts" : "2019-03-20T15:29:37",
      "v" : null,
      "q" : "0"
    } ]
  } ]
}

我需要它看起来像这样:

    {
      "tags" : [ {
        "tagId" : "G1.A_90LT1OUT",
        "data" : [ {
          "ts" : "2019-03-20T15:27:36",
          "v" : "96.2427826",
          "q" : "3"
        } ]
      }, {
        "tagId" : "G1.A_90LT1OUT",
        "data" : [ {
          "ts" : "2019-03-20T15:29:20",
          "v" : "96.2427826",
          "q" : "3"
        } ]
      }, {
        "tagId" : "G1.A_90LT1OUT",
        "data" : [ {
          "ts" : "2019-03-20T15:29:37",
          "v" : "96.2581177",
          "q" : "3"
        } ]
      } ]
    }

可以做到吗?请告诉我如何。对于JSON操纵来说,它还很陌生,我看过另一篇文章,展示了如何从节点中删除元素,但是我认为我的情况有些不同。我试图追逐文档毫无用处,也许是在错误的地方寻找。

先谢谢您。

1 个答案:

答案 0 :(得分:2)

JSONPath

对于JSON操作和过滤,您还可以使用JsonPath库。它有一个很棒的web tool,您可以在其中尝试不同的过滤器和选项。我们可以使用以下路径过滤所有不包含空值的节点:

$.tags[?(@.data[0].v != null)]

具有相同功能的示例应用程序:

import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;

import java.io.File;

public class JsonPathApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        JSONArray filtered = JsonPath.parse(jsonFile).read("$.tags[?(@.data[0].v != null)]");

        // Create root object
        JSONObject root = new JSONObject();
        root.appendField("tags", filtered);

        // Get JSON
        String json = root.toString();

        // Write JSON on console or file
        System.out.println(json);
    }
}

上面的代码显示:

{"tags":[{"tagId":"G1.A_90LT1OUT","data":[{"ts":"2019-03-20T15:27:36","v":"96.2427826","q":"3"}]},{"tagId":"G1.A_90LT1OUT","data":[{"ts":"2019-03-20T15:29:20","v":"96.2427826","q":"3"}]},{"tagId":"G1.A_90LT1OUT","data":[{"ts":"2019-03-20T15:29:37","v":"96.2581177","q":"3"}]}]}

Jackson

Jackson相同,我们可以通过这种方式实现:

  • 将JSON读取为树
  • 转到tags数组
  • 遍历数组
  • 对于每个项目,请在v元素中找到0-index
  • 如果它是null-删除它

示例实现:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        JsonNode root = mapper.readTree(jsonFile);
        ArrayNode tags = (ArrayNode) root.get("tags");
        Iterator<JsonNode> elements = tags.elements();
        while (elements.hasNext()) {
            JsonNode item = elements.next();
            ArrayNode data = (ArrayNode) item.get("data");
            JsonNode v = data.get(0).get("v");
            if (v.isNull()) {
                elements.remove();
            }
        }

        System.out.println(root);
    }
}