数组元素的 PlayJson 更新不起作用

PlayJson update on element of array does not work

我有一个json

val js =  Json.obj("val" -> Json.arr(Json.obj("a" -> Json.arr(1))))

我想更新它

Json.obj("val" -> Json.arr(Json.obj("a" -> Json.arr(1))))
  .transform((__ \ "val") (0).json.update(__.read[JsArray].map { jsVal => println(jsVal); jsVal }))

我的更新消息什么都不打印。甚至不调用调试。 但是 pick 方法找到了这个元素。

js.transform((__ \ "val")(0).json.pick)

return JsSuccess({"a":[1]},//val(0)) 我不明白为什么。 谁能帮我更新确切的元素。

你的地图没有被调用,因为 read[JsArray] 实际上 returns JsError:

val js = Json.obj("val" -> Json.arr(Json.obj("a" -> Json.arr(1))))
val result1 = js.transform((__ \ "val") (0).json.update(Reads.of[JsArray]))
println(result1)
// JsError(List((//val(0),List(JsonValidationError(List(error.expected.jsarray),WrappedArray())))))

您可以通过这种方式打印导致它的值:

val result2 = js.transform((__ \ "val")(0).json.update(
  Reads(v => { println(v); v.validate[JsArray] })
))
println(result2) 
// {"a":[1]} - same value as in pick!
// JsError(List((//val(0),List(JsonValidationError(List(error.expected.jsarray),WrappedArray()))))

现在我们知道它是一个物体所以让我们试着去触摸它

val result3 = js.transform((__ \ "val")(0).json.update(Reads.of[JsObject]))
println(result3)
// java.lang.RuntimeException: expected KeyPathNode

让我们检查一下更新的实现: https://github.com/playframework/play-json/blob/2.6.9/play-json/shared/src/main/scala/play/api/libs/json/JsConstraints.scala#L85-L94

基本上是:

  1. 从根对象读取(使用可选转换)由路径标识的值
  2. 创建一个仅包含这些路径和值的对象
  3. 将 JsObject.deepMerge 应用于根对象和 value-holding 一个

2)中使用的方法JsPath.createObj只能处理键指定的路径,不能处理索引指定的路径。所以似乎不可能在 play-json 中修改嵌套数组的元素,至少开箱即用。

同时在圈地: https://scastie.scala-lang.org/wRLs7O72ScyOmcMyiTU5uw