【问题标题】:Altering an array in a nested JSON object using Jackson使用 Jackson 更改嵌套 JSON 对象中的数组
【发布时间】:2017-04-18 21:06:25
【问题描述】:

我试图弄清楚如何通过指定该数组的路径来更改 JSON 数组中的现有对象。

问题是我不知道如何指定数组的路径以便可以更改它。我尝试过的每种方法都没有示例说明如何更改 ObjectNode 中的数组。

这是我现在的代码,在其中我尝试通过指针表示法指定数组的路径来获取和更改数组,但是,这总是不返回数组:

构建 POJO 类不是一种选择。

我的json结构中的数组如下:

{
  RESULTS: {
     ATTACHMENTS: {
       ATTACHMENT: [{object}]
  }
 }
}

代码:

   private JsonNode attachmentConversion(JsonNode object){
        final String ATTACHMENT_POINTER = "/RESULTS/ATTACHMENTS/ATTACHMENT"; //Path to the array
        ObjectNode OUTPUT = object.deepCopy();
        OUTPUT.remove("DETAILS");

        //Validate is an array - It properly fetches the array 
        if(object.at(ATTACHMENT_POINTER).isArray()){
            int counter=0;

            //Loop through attachment array - It properly fethes each object in the array
            for(final JsonNode objNode : object.at(ATTACHMENT_POINTER)){
                ObjectNode objectNode = objNode.deepCopy();
                OUTPUT.withArray(ATTACHMENT_POINTER) //HERE IS THE PROBLEM - How do I specify the path to the array I want to replace with a new object in the withArray api?  This always returns back as an empty array, even though the loop above properly fetches the array elements.
                        .set(counter
                                , objectNode
                                .replace("ATTACH_CONTENT"
                                        , xmlToJson.parseXmlToJson(objNode.get("ATTACH_CONTENT")
                                        .asText())));
                counter = counter+1;
            }
        }
        return new ObjectMapper()
                .createObjectNode()
                .set("customertopology", OUTPUT);
    }

【问题讨论】:

    标签: java jackson jackson-databind


    【解决方案1】:

    我认为你不想更改传递给方法的对象,所以你做了一个深拷贝。你想返回一个新的 JSON 对象。

    到目前为止我是对的吗?如果是,当您制作了深层副本时,使用它,遍历您关注的数组的每个元素,并将 Node 值替换为您想要的值。

    private static JsonNode attachmentConversion(JsonNode object){
    
    
    
        final String ATTACHMENT_POINTER = "/RESULTS/ATTACHMENTS/ATTACHMENT"; //Path to the array
        ObjectNode OUTPUT = object.deepCopy();
        OUTPUT.remove("DETAILS");
    
        //Validate is an array - It properly fetches the array
        if(OUTPUT.at(ATTACHMENT_POINTER).isArray()){
            int counter=0;
    
            //Loop through attachment array - It properly fethes each object in the array
            for(final JsonNode objNode : OUTPUT.at(ATTACHMENT_POINTER)){
                ((ObjectNode)objNode).replace("ATTACH_CONTENT", xmlToJson.parseXmlToJson(objNode.get("ATTACH_CONTENT"));
            }
    
        }
        return new ObjectMapper()
                .createObjectNode()
                .set("customertopology", OUTPUT);
    }
    

    【讨论】:

    • 谢谢这解决了。似乎问题在于在杰克逊 API 中使用 SET 与 REPLACE。我还注意到您将其投射到现有的 objNode 上,以便将其转换为解决问题的 ObjectNode。
    【解决方案2】:

    您可以这样做,而不是提供整个路径

    OUTPUT.get("RESULTS").get("ATTACHMENTS").get("ATTACHMENT");
    

    这应该返回数组。使用fastxml的完整代码

    String json = "{\n" +
                "  \"RESULTS\": {\n" +
                "     \"ATTACHMENTS\": {\n" +
                "       \"ATTACHMENT\": [{\"key\": 1}, {\"key\": 2}]\n" +
                "  }\n" +
                " }\n" +
                "}";
    
    ObjectMapper mapper = new ObjectMapper();
    JsonNode node = mapper.readTree(json);
    node.get("RESULTS").get("ATTACHMENTS").get("ATTACHMENT").forEach(obj -> {
            System.out.println(obj.get("key"));
        });
    

    以下代码对我来说也是正确的。

    System.out.println(node.at("/RESULTS/ATTACHMENTS/ATTACHMENT").isArray());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-07
      • 2021-11-28
      • 2019-08-11
      • 2019-04-05
      • 2020-11-03
      • 1970-01-01
      • 1970-01-01
      • 2014-03-12
      相关资源
      最近更新 更多