#scala #play-json
#scala #воспроизведение-json
Вопрос:
Я пытаюсь обновить значение json, присутствующее в json, используя Scala play framework.Вместо обновления значения оно добавляет значение.
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}}
Любая помощь по этому вопросу будет действительно приятной.
Ответ №1:
Цитирование из update
документации по методу:
(
__
‘key).json.update (reads) является самым сложным Reads [JSObject], но самым мощным:
копирует все значение JsValue => A
применяет переданные чтения [A] к JsValue => B
deep объединяет оба JsValues (A B), поэтому B перезаписывает идентичные ветви. Пожалуйста, обратите внимание, что если вы обрезали ветку в 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.