在play框架上的scala中从JsArray中提取字段

时间:2014-08-14 21:49:00

标签: scala playframework playframework-2.0

我在服务器上有一个类似下面的JSArray(我不能因为它属于其他人而改变):

[ {"name": "US", "id": 0, "translations" : {"name: {"es": "Estados unidos", "fr": "Etats-unis"}}},
{"name": "UK", "id": 1, "translations" : {"name: {"es": "Estados Kdda", "fr": "dsfjas"}}},
...
]

我需要提取所有名称,如美国,英国,但不是translations中的名称,也是id。

我尝试了几种方法,但总是有问题。以下是我的尝试。

我第一次尝试

case class Country(name: String, id:String) 

implicit object CountryReads extends Reads[Country] {  
def reads(json: JsValue) = Country(
                        (json \ "name"),
                        (json \ "id")
                    )
}

val countries = Json.parse(result) match {  //here result is Json String
           case JsArray(Seq(t)) => Some(t.as[Seq[Country]])
           case _ => None
}

但是我得到如下编译错误:

[error] C:\git9\hss\app\models\LivingSocial.scala:80: type mismatch;
[error]  found   : play.api.libs.json.JsValue
[error]  required: play.api.libs.json.JsResult[MyCountry]
[error]                        def reads(json: JsValue) =    (json \ "currencyCode")
[error]                                                            ^
[error] one error found
[error] (compile:compile) Compilation failed
然后我尝试了:

val jResult = Json.parse(result)
(jResult \\ "name").foreach { name => 
   println(name.as[String])
}

我在println()收到错误" \"将在翻译下递归拉取名字。

有什么好办法吗?

2 个答案:

答案 0 :(得分:2)

case class Country(name: String, id: Int, translations: Map[String, Map[String, String]])

object Country {

  implicit val format = Json.format[Country]

}

val js = Json.parse(yourString)

val names: JsResult[Seq[String]] = js.validate[Seq[Country]].map { countries => countries.map(_.name) }

此时您可以处理JsResult,因为如果JSON不符合您的期望,您将需要进行错误处理。

答案 1 :(得分:0)

您可以将阅读更改为:

implicit val CountryReads: Reads[Country] = (
        (JsPath \ "name").read[String] and
          (JsPath \ "name").read[String]
        )(Country.apply _)

这是根据播放文档创建阅读器的正确方法