在 Scala 中播放 Framework 2:解析可变 JSON 格式?
Play Framework 2 in Scala: Parsing variadic JSON format?
考虑以下示例 JSON:
properties: {
"key1": "a",
"key2": 1,
"key3": null,
"key4": 0.56
....
"key99": "zzzzz"
}
我的代码需要能够将其解析为某种 Scala 结构(案例 class?)并返回到 JSON。
对我来说,由于 properties
中的元素数量不是有限的,这看起来像 Map[String, T]
。由于每个内部 属性 的值可以是多种类型,我不确定如何将其表示为有限的 Scala 结构。关于隐式 Reads
、Writes
和 Formats
的文档对我来说很有意义,但它们似乎无法处理更复杂的示例,例如上面的示例。
也完全有可能我的想法是完全错误的。
我是框架(以及语言)的新手,我很难理解应该如何表示它——任何见解都将不胜感激。
正如@Tyth 所指出的,我们可能需要重新考虑您的 json 的结构。也许是这样的:
{ [ { "key" : "key1", "value" : "a" }, { "key" : "key2", "value" : "1" }, .....
会更好...
不过,要回答您的问题,您可以这样做:
import play.api.libs.json._
val a = """{
| "key1": "a",
| "key2": 1,
| "key3": null,
| "key4": 0.56 }
| """
val b = Json.parse(a)
val keys = b.as[JsObject].keys
并且您可以打印您的密钥
scala> keys.foreach { k => println( b \ k ) }
"a"
1
null
0.56
或者转成JsValue的map
scala> keys.map { k => k -> (b \ k) }.toMap
res4: scala.collection.immutable.Map[String,play.api.libs.json.JsValue] = Map(key1 -> "a", key2 -> 1, key3 -> null, key4 -> 0.56)
或字符串:
scala> keys.map { k => k -> (b \ k).toString }.toMap
res3: scala.collection.immutable.Map[String,String] = Map(key1 -> "a", key2 -> 1, key3 -> null, key4 -> 0.56)
编辑(根据补充评论):
scala> JsObject(b.as[JsObject].fields :+ ("key99" -> JsString("zzzz")))
res7: play.api.libs.json.JsObject = {"key1":"a","key2":1,"key3":null,"key4":0.56,"key99":"zzzz"}
考虑以下示例 JSON:
properties: {
"key1": "a",
"key2": 1,
"key3": null,
"key4": 0.56
....
"key99": "zzzzz"
}
我的代码需要能够将其解析为某种 Scala 结构(案例 class?)并返回到 JSON。
对我来说,由于 properties
中的元素数量不是有限的,这看起来像 Map[String, T]
。由于每个内部 属性 的值可以是多种类型,我不确定如何将其表示为有限的 Scala 结构。关于隐式 Reads
、Writes
和 Formats
的文档对我来说很有意义,但它们似乎无法处理更复杂的示例,例如上面的示例。
也完全有可能我的想法是完全错误的。
我是框架(以及语言)的新手,我很难理解应该如何表示它——任何见解都将不胜感激。
正如@Tyth 所指出的,我们可能需要重新考虑您的 json 的结构。也许是这样的:
{ [ { "key" : "key1", "value" : "a" }, { "key" : "key2", "value" : "1" }, .....
会更好...
不过,要回答您的问题,您可以这样做:
import play.api.libs.json._
val a = """{
| "key1": "a",
| "key2": 1,
| "key3": null,
| "key4": 0.56 }
| """
val b = Json.parse(a)
val keys = b.as[JsObject].keys
并且您可以打印您的密钥
scala> keys.foreach { k => println( b \ k ) }
"a"
1
null
0.56
或者转成JsValue的map
scala> keys.map { k => k -> (b \ k) }.toMap
res4: scala.collection.immutable.Map[String,play.api.libs.json.JsValue] = Map(key1 -> "a", key2 -> 1, key3 -> null, key4 -> 0.56)
或字符串:
scala> keys.map { k => k -> (b \ k).toString }.toMap
res3: scala.collection.immutable.Map[String,String] = Map(key1 -> "a", key2 -> 1, key3 -> null, key4 -> 0.56)
编辑(根据补充评论):
scala> JsObject(b.as[JsObject].fields :+ ("key99" -> JsString("zzzz")))
res7: play.api.libs.json.JsObject = {"key1":"a","key2":1,"key3":null,"key4":0.56,"key99":"zzzz"}