Play Framework Json 递归转换
Play Framework Json Transform recursivly
一段时间以来,我一直在解决以下问题。
我尝试通过 tree-like json 结构进行递归转换。
{
"id": 21,
"title": "Title1",
"children": [
{
"id": 22,
"title": "Title1.1",
"children": [
{
"id": 33,
"title": "Title1.1.1",
"children": [
{
"id": 41,
"title": "Title1.1.1.1",
"children": [
{
"id": 42,
"title": "Title1.1.1.1.1",
}
]
}
]
}
]
}
]
}
到目前为止我有:
val idChanger:Reads[JsObject] = (__ \ 'id).json.update(of[JsNumber].map{case JsNumber(nb) => JsNumber(nb * 100)})
val childPicker:Reads[JsValue] = (__ \ 'children).json.pick[JsArray].map{
case JsArray(arr) => JsArray(arr.map(o => {
o.transform(idChanger) match {
case JsSuccess(value, jsPath) =>
println(s"Success:$value")
value
case JsError(errors) =>
println(s"Error:$errors"); JsNull
}
}))
}
val jsvalue: JsValue = ...
jsvalue.transform(childPicker)
...
这仅适用于第一层,并相应地更改 ID“21”,但到目前为止还不能更改其余部分。
我也尝试了很多不同的方法来递归完成 children 的其余部分,但到目前为止没有成功。
如有任何帮助,我们将不胜感激。
干杯,罗伯
只需在 Reads 中添加递归调用,并确保处理 JsArray 和 JsObject。这是一个符合这个基本思想的简单例子。
val idChanger: Reads[JsObject] =
(__ \ 'id).json.update(of[JsNumber].map{case JsNumber(nb) => JsNumber(nb * 100)})
val picker: Reads[JsValue] = __.json.pick.map{
case JsArray(arr) => JsArray(arr.map(_.transform(picker).get))
case v: JsValue =>
v.transform(
idChanger andThen (__ \ "children").json.update(picker) orElse
idChanger
).get
}
一段时间以来,我一直在解决以下问题。
我尝试通过 tree-like json 结构进行递归转换。
{
"id": 21,
"title": "Title1",
"children": [
{
"id": 22,
"title": "Title1.1",
"children": [
{
"id": 33,
"title": "Title1.1.1",
"children": [
{
"id": 41,
"title": "Title1.1.1.1",
"children": [
{
"id": 42,
"title": "Title1.1.1.1.1",
}
]
}
]
}
]
}
]
}
到目前为止我有:
val idChanger:Reads[JsObject] = (__ \ 'id).json.update(of[JsNumber].map{case JsNumber(nb) => JsNumber(nb * 100)})
val childPicker:Reads[JsValue] = (__ \ 'children).json.pick[JsArray].map{
case JsArray(arr) => JsArray(arr.map(o => {
o.transform(idChanger) match {
case JsSuccess(value, jsPath) =>
println(s"Success:$value")
value
case JsError(errors) =>
println(s"Error:$errors"); JsNull
}
}))
}
val jsvalue: JsValue = ...
jsvalue.transform(childPicker)
...
这仅适用于第一层,并相应地更改 ID“21”,但到目前为止还不能更改其余部分。
我也尝试了很多不同的方法来递归完成 children 的其余部分,但到目前为止没有成功。
如有任何帮助,我们将不胜感激。
干杯,罗伯
只需在 Reads 中添加递归调用,并确保处理 JsArray 和 JsObject。这是一个符合这个基本思想的简单例子。
val idChanger: Reads[JsObject] =
(__ \ 'id).json.update(of[JsNumber].map{case JsNumber(nb) => JsNumber(nb * 100)})
val picker: Reads[JsValue] = __.json.pick.map{
case JsArray(arr) => JsArray(arr.map(_.transform(picker).get))
case v: JsValue =>
v.transform(
idChanger andThen (__ \ "children").json.update(picker) orElse
idChanger
).get
}