如何使用scala-play框架更新嵌套json



我正在尝试使用Scala播放框架更新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}}

这方面的任何帮助都会非常好。

引用update方法文档:

(__\'key(.json.update(reads(是最复杂的reads[JsObject]但最强大的:

  • 复制整个JsValue=>

  • 将传递的Reads[A]应用于JsValue=>B

  • deep合并了两个JsValue(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找到它。

最新更新