【问题标题】:Removing JSON elements with jackson使用杰克逊删除 JSON 元素
【发布时间】:2013-03-24 19:37:45
【问题描述】:

我有一个特定的 JSON 节点对应于 import org.codehaus.jackson.JsonNode,而不是 导入 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”。有没有办法实现这一目标?

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

    我没有对此进行测试,但我认为这样的事情会做你想要的:

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

    您也可以使用 Jackon 的原始解析 API 更有效地执行此操作,但代码会更加混乱。

    【讨论】:

      【解决方案2】:

      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);
      

      【讨论】:

      • 您也可以使用((ObjectNode)node).remove(Collection<String>),例如((ObjectNode)node).remove(Arrays.asList("familyName","middleName"));
      【解决方案3】:

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

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

      前三个元素代表一个人和一个相应的分数对象。最后一个“警告”,与分数对象不匹配,这就是我要删除的那个。

      从上面 gsteff 的回答中将 rootNode 作为起始 JsonNode,我发现删除它的方法是遍历每个节点,将节点的对象映射版本添加到 HashMap,这是我想要的返回对象想要除非它是“警告”元素:

      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;
      

      【讨论】:

        【解决方案4】:

        gsteff写的答案也可以用,不过我觉得更简单的方法是用对象映射器转换成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);
                }
        

        【讨论】:

        • 我不知道这有多容易
        【解决方案5】:

        According to the JSONObject documentation,JSONObject 实现了 Map.remove,它返回存储在该键处的值。像这样使用它

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

        【讨论】:

        • 这是关于 JsonNode,而不是 JsonObject。
        【解决方案6】:

        我需要的是从具有特定前缀的键的平面根对象中删除元素。我的解决方案是这样的:

        Iterator<String> it = jsonNode.fieldNames();
                while (it.hasNext()) {
                    String nextKey = it.next();
                    if (nextKey.startsWith("prefix")) {
                        it.remove();
                        ((ObjectNode)jsonNode).remove(nextKey);
                    }
                }
        

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

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-11-25
            • 1970-01-01
            • 2019-05-02
            • 2014-02-12
            • 1970-01-01
            相关资源
            最近更新 更多