public static JsonNode merge(JsonNode mainNode, JsonNode updateNode) {
Iterator<String> fieldNames = updateNode.fieldNames();
while (fieldNames.hasNext()) {
String updatedFieldName = fieldNames.next();
JsonNode valueToBeUpdated = mainNode.get(updatedFieldName);
JsonNode updatedValue = updateNode.get(updatedFieldName);
// If the node is an @ArrayNode
if (valueToBeUpdated != null && valueToBeUpdated.isArray() &&
updatedValue.isArray()) {
// running a loop for all elements of the updated ArrayNode
for (int i = 0; i < updatedValue.size(); i++) {
JsonNode updatedChildNode = updatedValue.get(i);
// Create a new Node in the node that should be updated, if there was no corresponding node in it
// Use-case - where the updateNode will have a new element in its Array
if (valueToBeUpdated.size() <= i) {
((ArrayNode) valueToBeUpdated).add(updatedChildNode);
}
// getting reference for the node to be updated
JsonNode childNodeToBeUpdated = valueToBeUpdated.get(i);
merge(childNodeToBeUpdated, updatedChildNode);
}
// if the Node is an @ObjectNode
} else if (valueToBeUpdated != null && valueToBeUpdated.isObject()) {
merge(valueToBeUpdated, updatedValue);
} else {
if (mainNode instanceof ObjectNode) {
((ObjectNode) mainNode).replace(updatedFieldName, updatedValue);
}
}
}
return mainNode;
}
def mergeYamlObjects(source: ObjectNode, target: ObjectNode, overwrite: Boolean = true): ObjectNode = {
if (target == null)
source
else if (source == null)
target
else {
val result = source.deepCopy
val fieldlist = source.fieldNames.asScala.toList ++ target.fieldNames.asScala.toList
for (item <- fieldlist) {
if (!(source has item)) {
result put(item, target get item)
} else {
if ((source get item).isValueNode) {
if (target has item)
if (overwrite)
result.put(item, target get item)
} else {
result.put(item, mergeYamlObjects(source.get(item).asInstanceOf[ObjectNode],
target.get(item).asInstanceOf[ObjectNode], overwrite = overwrite))
}
}
}
result
}
}
7条答案
按热度按时间rsaldnfx1#
受StaxMans回答的启发,我实现了这个合并方法。
希望这能帮到什么人。
zaq34kh62#
一种方法是这样使用
ObjectReader
:它将合并来自两个源的数据。这只做一个浅副本,即不对包含的对象做递归合并。
否则,您可能需要将JSON作为树(
JsonNode
)读取,循环遍历内容并手动合并。这通常是有意义的,因为合并规则并不是微不足道的,每个人都有自己的合并工作方式。编辑:(2017年4月3日)
根据@费尔南多·科雷亚的评论,实际上在即将到来的Jackson2.9(将于2017年4月或5月发布)中添加了一个新的feature,它最终允许深度合并。
5uzkadbs3#
受Arn答案的启发,对它进行了编辑,添加了一个节点可能包含一个节点数组的情况。
xeufq47z4#
下面是Scala的一个实现。源节点和目标节点通常是可交换的,除非分支同时存在于源节点和目标节点中。
yh2wf1be5#
如果有人只是想将两个或多个JsonNode对象添加到一个JsonNode中,可以使用以下方法:
l2osamch6#
下面是将两个JSON树合并为一个的完整实现。希望对您有所帮助:)
fxnxkyjh7#
如果您的目标是连接两个JSON,我发现最简单的方法如下(考虑到您已经准备好了两个ObjecNode):
希望能有所帮助