如何使用JsonPath向Json添加新节点?

yptwkmov  于 5个月前  发布在  其他
关注(0)|答案(4)|浏览(73)

我正在使用JSON,遇到了一些问题。
我想在JSON对象中插入/更新一个路径。如果路径不存在,它将被创建,然后我插入一个新值。如果它退出,它将被一个新值更新
例如,我想像这样添加新路径:

val doc = JsonPath.parse(jsonString)
doc.add("$.user.name", "John")

字符串
但我总是得到这个错误,因为路径不存在:
class com.jayway.jsonpath.PathNotFoundException:路径$“user”中缺少属性]
因此,我想创建一个新的路径,如果它不存在。
这是我的代码,但jsonString没有改变:

var jsonString = "{}" val conf = Configuration.defaultConfiguration().addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL).addOptions(Option.SUPPRESS_EXCEPTIONS)
JsonPath.using(conf).parse(jsonString).set(JsonPath.compile("$.user.name"), "John") 
Log.d("TAG", "new json = $jsonString")


请给我给予。非常感谢!!

4nkexdtk

4nkexdtk1#

我尝试了三种不同的JSON库,它们都支持JsonPath/JsonPointer(Jackson,JsonPath和JSON-P),但在缺少父节点的情况下,它们都无法重建JSON对象层次结构。因此,我提出了自己的解决方案,使用Jackson/JsonPointer向JSON对象添加新值,因为它允许在JsonPointer部分中导航。

private static final ObjectMapper mapper = new ObjectMapper();

public void setJsonPointerValue(ObjectNode node, JsonPointer pointer, JsonNode value) {
    JsonPointer parentPointer = pointer.head();
    JsonNode parentNode = node.at(parentPointer);
    String fieldName = pointer.last().toString().substring(1);

    if (parentNode.isMissingNode() || parentNode.isNull()) {
        parentNode = StringUtils.isNumeric(fieldName) ? mapper.createArrayNode() : mapper.createObjectNode();
        setJsonPointerValue(parentPointer, parentNode); // recursively reconstruct hierarchy
    }

    if (parentNode.isArray()) {
        ArrayNode arrayNode = (ArrayNode) parentNode;
        int index = Integer.valueOf(fieldName);
        // expand array in case index is greater than array size (like JavaScript does)
        for (int i = arrayNode.size(); i <= index; i++) {
            arrayNode.addNull();
        }
        arrayNode.set(index, value);
    } else if (parentNode.isObject()) {
        ((ObjectNode) parentNode).set(fieldName, value);
    } else {
        throw new IllegalArgumentException("`" + fieldName + "` can't be set for parent node `"
                + parentPointer + "` because parent is not a container but " + parentNode.getNodeType().name());
    }
}

字符串
使用方法:

ObjectNode rootNode = mapper.createObjectNode();

setJsonPointerValue(rootNode, JsonPointer.compile("/root/array/0/name"), new TextNode("John"));
setJsonPointerValue(rootNode, JsonPointer.compile("/root/array/0/age"), new IntNode(17));
setJsonPointerValue(rootNode, JsonPointer.compile("/root/array/4"), new IntNode(12));
setJsonPointerValue(rootNode, JsonPointer.compile("/root/object/num"), new IntNode(81));
setJsonPointerValue(rootNode, JsonPointer.compile("/root/object/str"), new TextNode("text"));
setJsonPointerValue(rootNode, JsonPointer.compile("/descr"), new TextNode("description"));

System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode));


这将生成并打印以下JSON对象:

{
  "root" : {
    "array" : [ {
      "name" : "John",
      "age" : 17
    }, null, null, null, 12 ],
    "object" : {
      "num" : 81,
      "str" : "text"
    }
  },
  "descr" : "description"
}


当然,这并不能涵盖所有的角落情况下,但在大多数情况下工作。希望这有助于别人。

rta7y2nd

rta7y2nd2#

要创建一个新节点,请尝试在JsonPath.parse(jsonString)的结果实现的WriteContext接口上使用put(path,key,object)。

cfh9epnr

cfh9epnr3#

你可以这样做:

JsonPath.parse(jsonString).set(JsonPath.compile("$.user.name"), "John");

字符串

ogsagwnx

ogsagwnx4#

Put将帮助您添加或更新密钥:

JsonPath.parse(jsonString).put("user", "name", "John");

字符串

相关问题