将 JSON 结构转换为管道格式
Transform JSON structure to piped format
是否有一种快速简便的方法来转换 JsObject,例如
Json.obj(
"title" -> "Working Title",
"author" -> Json.obj(
"name" -> "Peter Trunes",
"location" -> Json.obj(
"birthplace" -> "Perth",
"nationality" -> "Australian",
..
),
..
),
..
)
转换为 JsPath
为所有嵌套 jsObjects
管道传输的格式?例如
Json.obj(
"title" -> "Working Title",
"author.name" -> "Peter Trunes",
"author.location.birthplace" -> "Perth",
"author.location.nationality" -> "Australian",
..
)
我正在使用转换器来使用海岸到海岸技术(如 documented here)来操纵 Json 数据结构,并且我能够像这样为 author
执行此操作:
def authorTrans: Reads[JsObject] =
(__ \ 'author).read[JsObject].flatMap(
_.fields.foldLeft((__ \ 'author).json.prune) {
case (acc, (k, v)) => acc andThen __.json.update(
Reads.of[JsObject].map(_ + (s"author.$k" -> v))
)
}
)
def tryTransformAsJsObj(obj: JsValue, transformer: Reads[JsObject]) = {
obj.transform(transformer) match {
case JsSuccess(r: JsObject, _) => r
case e: JsError => JsError.toJson(e)
}
}
tryTransformAsJsObj(jso, authorTrans) // jso is the JsObject structure to be transformed
我在这里尝试使用递归方法来转换每个嵌套 JsObject
但我正在努力使它正确,并且想知道我是否错过了一种更简单的技术。欢迎提出想法和建议!
这里有一些递归代码,你应该扩展模式匹配以涵盖所有情况,否则你会收到警告:
import play.api.libs.json.{JsObject, JsString, JsValue, Json}
val original = Json.obj(
"title" -> "Working Title",
"author" -> Json.obj(
"name" -> "Peter Trunes",
"location" -> Json.obj(
"birthplace" -> "Perth",
"nationality" -> "Australian"
)
)
)
def transform(input: scala.collection.Map[String, JsValue], accum: JsObject,
curPath: String): JsObject = {
val result = input.foldLeft(accum) {
case (acc, (k, v)) =>
v match {
case JsString(str) => acc + (curPath + k -> Json.toJson(str))
case JsObject(kvs) =>
val newPath = if (curPath.isEmpty) s"$k." else s"$curPath$k."
transform(kvs, acc, newPath)
}
}
result
}
transform(original.value, Json.obj(), "")
是否有一种快速简便的方法来转换 JsObject,例如
Json.obj(
"title" -> "Working Title",
"author" -> Json.obj(
"name" -> "Peter Trunes",
"location" -> Json.obj(
"birthplace" -> "Perth",
"nationality" -> "Australian",
..
),
..
),
..
)
转换为 JsPath
为所有嵌套 jsObjects
管道传输的格式?例如
Json.obj(
"title" -> "Working Title",
"author.name" -> "Peter Trunes",
"author.location.birthplace" -> "Perth",
"author.location.nationality" -> "Australian",
..
)
我正在使用转换器来使用海岸到海岸技术(如 documented here)来操纵 Json 数据结构,并且我能够像这样为 author
执行此操作:
def authorTrans: Reads[JsObject] =
(__ \ 'author).read[JsObject].flatMap(
_.fields.foldLeft((__ \ 'author).json.prune) {
case (acc, (k, v)) => acc andThen __.json.update(
Reads.of[JsObject].map(_ + (s"author.$k" -> v))
)
}
)
def tryTransformAsJsObj(obj: JsValue, transformer: Reads[JsObject]) = {
obj.transform(transformer) match {
case JsSuccess(r: JsObject, _) => r
case e: JsError => JsError.toJson(e)
}
}
tryTransformAsJsObj(jso, authorTrans) // jso is the JsObject structure to be transformed
我在这里尝试使用递归方法来转换每个嵌套 JsObject
但我正在努力使它正确,并且想知道我是否错过了一种更简单的技术。欢迎提出想法和建议!
这里有一些递归代码,你应该扩展模式匹配以涵盖所有情况,否则你会收到警告:
import play.api.libs.json.{JsObject, JsString, JsValue, Json}
val original = Json.obj(
"title" -> "Working Title",
"author" -> Json.obj(
"name" -> "Peter Trunes",
"location" -> Json.obj(
"birthplace" -> "Perth",
"nationality" -> "Australian"
)
)
)
def transform(input: scala.collection.Map[String, JsValue], accum: JsObject,
curPath: String): JsObject = {
val result = input.foldLeft(accum) {
case (acc, (k, v)) =>
v match {
case JsString(str) => acc + (curPath + k -> Json.toJson(str))
case JsObject(kvs) =>
val newPath = if (curPath.isEmpty) s"$k." else s"$curPath$k."
transform(kvs, acc, newPath)
}
}
result
}
transform(original.value, Json.obj(), "")