我正在尝试使用Scala play框架更新json中存在的json值,而不是更新值,而是附加值。
val newJsonString = """{"P123": 25}"""
val jsonStringAsJsValue = Json.parse("""{"counter_holders": {"Peter": 25}}""")
//jsonStringAsJsValue: play.api.libs.json.JsValue = {"counter_holders":{"Peter":25}}
val jsonTransformer = (__ \"counter_holders" ).json.update(__.read[JsValue].map{o => Json.parse(newJsonString)})
jsonStringAsJsValue.transform(jsonTransformer).get.as[JsValue]
//Now getting this jsvalue
//play.api.libs.json.JsValue = {"counter_holders":{"Peter":25,"P123":25}}
//But need this jsvalue
//play.api.libs.json.JsValue = {"counter_holders":{"P123":25}}
任何对此的帮助都会非常好。
答案 0 :(得分:1)
从update
方法文档中引用:
({
__
\'key).json.update(reads)是最复杂的读取[JsObject] 但最强大的:
复制整个JsValue => A
在JsValue => B上应用传递的Reads [A]
深度合并两个JsValues(A ++ B),因此B覆盖A相同的分支请注意,如果在B中修剪了一个分支,则仍然 在A中,您将在结果示例中看到它:
{{{ val js = Json.obj("key1" -> "value1", "key2" -> "value2") js.validate(__.json.update((__ \ 'key3).json.put(JsString("value3")))) => JsSuccess({"key1":"value1","key2":"value2","key3":"value3"},) }}}
因此,您看到的行为是预期的。如果要采用这种方法,即使用路径进行更新,则可以使用方法prune。例如,您可以这样做:
val newJsonString = """{"P123": 25}"""
val jsonStringAsJsValue = Json.parse("""{"counter_holders": {"Peter": 25}}""")
//jsonStringAsJsValue: play.api.libs.json.JsValue = {"counter_holders":{"Peter":25}}
val jsonTransformer = (__ \"counter_holders" ).json
.update(__.read[JsValue].map{o => Json.parse(newJsonString)})
val jsonTransformerDelete = (__ \"counter_holders" \ "Peter" ).json.prune
jsonStringAsJsValue.transform(jsonTransformer).flatMap(_.transform(jsonTransformerDelete)) match {
case JsSuccess(value, _) =>
println(value)
case JsError(errors) =>
println(errors)
}
这将产生想要的行为。您可以在scastie中找到它。