在play框架JsObject中解析Json数组

时间:2014-02-26 15:07:54

标签: json scala playframework-2.0

我有以下Json:

{
  "web-category" : "macaroons",
  "sub-categories" : [
     { "name" : "pink" },
     { "name" : "blue" },
     { "name" : "green" }
  ]

}

我在Play中作为JsObject获得了它。所以我现在可以成功地做到以下几点:

//(o is the JsObject)

val webCat:Option[String] = (o \ "web-category").asOpt[String]

println(webCat.toString)

>> Some(macaroons)

到目前为止,这么好。但是如何访问数组Json对象?我有这个......

val subCats:Option[JsArray] = (o \ "sub-categories").asOpt[JsArray]

println(subCats.toString)

>> Some([{"name" : "blue"},{"name" : "green"},{"name" : "pink"}])

但我需要的是获取JsArray并获取所有名称的列表:

List("blue", "green", "pink")

不知道如何访问JsArray。

感谢你的帮助。

3 个答案:

答案 0 :(得分:30)

我认为,尽早从JSON-land迁移到本地Scala-representation-land通常是一个好主意。例如,如果obj是您的JsObject,则可以写下:

val subCategories = (obj \ "sub-categories").as[List[Map[String, String]]]

val names = subCategories.map(_("name"))

甚至:

case class Category(name: String, subs: List[String])

import play.api.libs.functional.syntax._

implicit val categoryReader = (
  (__ \ "web-category").read[String] and
  (__ \ "sub-categories").read[List[Map[String, String]]].map(_.map(_("name")))
)(Category)

然后:

obj.as[Category]

后一种方法使得错误处理更加清晰(例如,您可以在此顶级使用as替换asOpt)并与其他Reads类型类实例很好地组合 - 如果您有例如,JsArray这些对象,您只需编写array.as[List[Category]]并获得您期望的内容。

答案 1 :(得分:10)

彼得说的话,或者:

(o \ "sub-categories" \\ "name").map(_.as[String]).toList

答案 2 :(得分:4)

这样的事情:

subCats.map( jsarray => jsarray.value.map(jsvalue => (jsvalue \ "name").as[String]).toList)

这通常会返回Option[List[String]]