Play 2.4.1:如何替换JSON树中所有出现的一个或多个键

时间:2015-07-05 17:43:03

标签: json scala playframework

给出以下JSON ......

{
  "id" : "52fe942b790000790079b7d0",
  "email" : "joe@domain.com",
  "username" : "joe",
  "subscriptions" : [
    {
      "accountId" : "72fe942b790000790079b755",
      "name" : "test 1",
      "isDefault" : true
    },
    {
      "accountId" : "72fe942b796850790079b743",
      "name" : "test 2",
      "isDefault" : false
    }
  ]
}

..我需要根据MongoDB的要求将每个id转换为ObjectID(即id - > _id \ $oidaccountId - > accountId \ $oid

{
  "_id" : {"$oid" : "52fe942b790000790079b7d0"},
  "email" : "joe@domain.com",
  "username" : "joe",
  "subscriptions" : [
    {
      "accountId" : {"$oid" : "72fe942b790000790079b755"},
      "name" : "test 1",
      "isDefault" : true
    },
    {
      "accountId" : {"$oid" : "72fe942b796850790079b743"},
      "name" : "test 2",
      "isDefault" : false
    }
  ]
}

最多播放2.3.8我使用play-json-zipperupdateAllKeyNodes做了诀窍:

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

json.updateAllKeyNodes {
  case ((_ \ "_id"), value) => "id" -> value \ "$oid"
  case ((_ \ "accountId"), value) => "accountId" -> value \ "$oid"
}

不幸的是,使用play 2.4.1我必须从项目中删除play-json-zipper,因为它不支持新的JSON模型。

使用标准Play JSON库获得相同结果的正确替代方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以将-+JsObject一起使用。

val json = Json.parse("""{"id":"123","a":1}""")

val id = (json \ "id").as[JsString] // find the id
val fixed = json.as[JsObject] - ("id") + ("_id", id) // replace

对于更复杂的要求:

Json.parse(str) match
  case JsObject(j) =>
    val newId = JsObject(Seq("$old" -> j("id")))
    val newSs = j("subscriptions") match {
      case JsArray(ss) => JsArray(ss.map {
        case JsObject(s) =>
          val i = s("accountId").as[JsString]
          val n = JsObject(Seq("$old" -> i))
          JsObject(s + ("accountId" -> n))
      })
    }
    JsObject(j - "id" + ("_id" -> newId) + ("subscriptions" -> newSs))
}