Play Framework:如何替换JSON树中所有值的出现

时间:2014-02-15 12:48:48

标签: json scala playframework

给出以下JSON ......

{ "id":"1234",
  "name" -> "joe",
  "tokens: [{
     "id":"1234",
     "id":"2345"
   }]
}

...我需要将所有id的值替换为xxxx,如下所示:

{ "id":"xxxx",
  "name" -> "joe",
  "tokens: [{
     "id":"xxxx",
     "id":"xxxx"
   }]
}

让我们开始创建JSON树:

val json = Json.obj(
  "id" -> "1234",
  "name" -> "joe",
  "tokens" -> Json.arr(
     Json.obj("id" -> "1234"),
     Json.obj("id" -> "2345")
  )
)

json: play.api.libs.json.JsObject = {"id":"1234","name":"joe","tokens":[{"id":"1234"},{"id":"2345"}]}

然后,获取所有id非常简单:

 json \\ "id"

 res64: Seq[play.api.libs.json.JsValue] = List("1234", "1234", "2345")

现在,如何用id替换所有xxxx的值?

2 个答案:

答案 0 :(得分:6)

使用标准的Play JSON库似乎并不是一个很好的方法,尽管我很高兴在这方面被证明是错误的。但是,您可以使用play-json-zipper扩展程序轻松完成此操作:

import play.api.libs.json._
import play.api.libs.json.extensions._

val json = Json.obj(
  "id" -> "1234",
  "name" -> "joe",
  "tokens" -> Json.arr(
    Json.obj("id" -> "1234"),
    Json.obj("id" -> "2345")
  )
)

// Using `updateAll` we pattern match on a path (ignoring
// the existing value, as long as it's a string) and replace it
val transformed = json.updateAll {
  case (__ \ "id", JsString(_)) => JsString("xxxx")
}

// play.api.libs.json.JsValue = {"id":"xxxx","name":"joe","tokens":[{"id":"xxxx"},{"id":"xxxx"}]}

使其成为可重复使用的功能:

def replaceValue(json: JsValue, key: String, replacement: String) = json.updateAll {
  case (__ \ path, JsString(_)) if path == key => JsString(replacement)
}

json-zipper扩展程序仍处于" experimental",但如果要将它们添加到项目中,请将以下内容添加到project/Build.scala appDependencies:

"play-json-zipper" %% "play-json-zipper" % "1.0"

以及以下解析器:

"Mandubian repository releases" at "https://github.com/mandubian/mandubian-mvn/raw/master/releases/"

答案 1 :(得分:0)

可能这不是最有效的方法,但你可以尝试将你的JSON转换为一个对象,用新字段复制它,然后将它转换回json。不幸的是,目前我没有环境来检查代码,但它应该是这样的:

case class MyId(id: String)
case class MyObject(id: String, name: String, tokens: List[MyId])

implicit val idFormat = Json.format[MyId]
implicit val objectFormat = Json.format[MyObject]

val json = Json.parse(jsonString)
val jsResult = Json.fromJson[MyObject](json)

val obj = jsResult match {
      case JsSuccess(s, _) => s
      case _ => throw new IllegalStateException("Unexpected")
    }

val newObj = obj.copy(id = "xxxx")
val result = Json.toJson(newObj)