问题
I am trying to update a json value present within a json using Scala play framework.Instead of updating the value it is appending the value.
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}}
Any help on this will be really nice.
回答1:
Quoting from the update
method docs:
(
__
\ 'key).json.update(reads) is the most complex Reads[JsObject] but the most powerful:
copies the whole JsValue => A
applies the passed Reads[A] on JsValue => B
deep merges both JsValues (A ++ B) so B overwrites A identical branches Please note that if you have prune a branch in B, it is still in A so you'll see it in the result Example:
{{{ val js = Json.obj("key1" -> "value1", "key2" -> "value2") js.validate(__.json.update((__ \ 'key3).json.put(JsString("value3")))) => JsSuccess({"key1":"value1","key2":"value2","key3":"value3"},) }}}
Therefore the behaviour you see is as expected. If you want to take that approach, of updating using the path, you can use the method prune. For example you can do:
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)
}
which will produce the wanted behaviour. You can find it in scastie.
来源:https://stackoverflow.com/questions/64280699/how-to-update-a-nested-json-using-scala-play-framework