如何使用 scala play 框架更新嵌套的 json?
How to update a nested json using scala play framework?
我正在尝试更新 json 中存在的 json 值,使用 Scala play framework.Instead 更新附加值的值。
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}}
任何帮助都将非常好。
引用自 update
方法文档:
(__
\ '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"},) }}}
因此,您看到的行为符合预期。如果你想采用这种方法,使用路径更新,你可以使用方法 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.
中找到它
我正在尝试更新 json 中存在的 json 值,使用 Scala play framework.Instead 更新附加值的值。
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}}
任何帮助都将非常好。
引用自 update
方法文档:
(
__
\ '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"},) }}}
因此,您看到的行为符合预期。如果你想采用这种方法,使用路径更新,你可以使用方法 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.
中找到它