如何使用 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.

中找到它