在Scala Play中解析JS

时间:2017-03-02 09:40:11

标签: json scala playframework

目标是从以下json中找到保时捷作为汽车的人的身份证明:

{
    "people": [
        {
           "id": "1",
           "name": "John",
           "car": "Ford"
        },
        {
           "id": "2",
           "name": "Andrew",
           "car": "Porsche"
        },
        {
           "id": "3",
           "name": "Joshua",
           "car": "Mercedes"
        }
    ]
}

以此为例:https://www.playframework.com/documentation/2.5.x/ScalaJsonCombinators,我找不到任何允许我这样做的代码:

在people数组中找到汽车价值为“Porsche”的节点,然后从该节点中检索ID。

val cars = json \ "people" \\ "car"

返回汽车列表,但这不是我想要做的。

有没有一种简单的方法可以对Json进行查询?

1 个答案:

答案 0 :(得分:2)

执行以下操作。首先创建一个表示json结构的case类。

case class Person(id: String, name: String, car: String)

object Person {
 implicit val personFormat = Json.format[Person]
}

case class People(people: List[Person])

object People {
  implicit val peopleFormat = Json.format[People]
}

Scala REPL

Now parse the json
scala> val str = """
     | {
     |     "people": [
     |         {
     |            "id": "1",
     |            "name": "John",
     |            "car": "Ford"
     |         },
     |         {
     |            "id": "2",
     |            "name": "Andrew",
     |            "car": "Porsche"
     |         },
     |         {
     |            "id": "3",
     |            "name": "Joshua",
     |            "car": "Mercedes"
     |         }
     |     ]
     | }
     | """.trim

scala> Json.parse(str).validate[People]
res5: play.api.libs.json.JsResult[People] = JsSuccess(People(List(Person(1,John,Ford), Person(2,Andrew,Porsche), Person(3,Joshua,Mercedes))),/people)

scala> Json.parse(str).validate[People] match {
     | case JsSuccess(value, _) => value.people.collectFirst { case Person(id, _, "Porsche") => id }
     | case JsError(errors) => None
     | }
res7: Option[String] = Some(2)

最后解析并收集第一个

Json.parse(str).validate[People] match {
  case JsSuccess(value, _) => value.people.collectFirst { case Person(id, _, "Porsche") => id }
  case JsError(errors) => None
}