djohon
djohon

Reputation: 879

How to parse second level JSON Array with play json library?

Here is my Json:

{
  "root": {
    "qr": {
      "content": "V1"
    },
    "datag": {
      "content": {

        "business": {
          "content": [
            {
              "content": "car"
            },
            {
              "content": "bike"
            }
          ]
        }

      }
    }
  }
}

Here is my attempt but i receive compilation error:

implicit val reads: Reads[rules] = (
   (JsPath \ "content" \ "qr" \ "content").readNullable[String] and
    (JsPath \ "content" \ "datag" \ "content" \ "business" \ "content").readNullable[Seq[String]]
 )(rules.apply _)   

What's the best way to parse it as a list of string?

Upvotes: 0

Views: 1128

Answers (2)

Arpit Suthar
Arpit Suthar

Reputation: 754

If you want your answer as a List("car","bike") as per your comment and you are looking for a one liner, you can try this

val json = Json.parse("""{
 |   "root": {
 |     "qr": {
 |       "content": "V1"
 |     },
 |     "datag": {
 |       "content": {
 | 
 |         "business": {
 |           "content": [
 |             {
 |               "content": "car"
 |             },
 |             {
 |               "content": "bike"
 |             }
 |           ]
 |         }
 | 
 |       }
 |     }
 |   }
 | }""")

val contents = (json \ "root" \ "datag" \ "content" \ "business" \ "content" ).as[List[Map[String, String]]].flatMap(_.values)
//this can throw an error if the data under 'content' is not a List
val contentsNew = (json \ "root" \ "datag" \ "content" \ "business" \ "content" ).asOpt[List[Map[String, String]]].map(_.flatMap(_.values)).fold(List.empty[String])(identity)
//this one is safe option 

or but I would suggest to create a case class and then use Json.format[CaseClass] you can take a look at this link.

Upvotes: 1

Rumesh Krishnan
Rumesh Krishnan

Reputation: 443

You can use the scala json parser to convert the json string into Map[String,Any] then get the value using key.

import scala.util.parsing.json._
val jsonString =
    """{
      |  "root": {
      |    "qr": {
      |      "content": "V1"
      |    },
      |    "datag": {
      |      "content": {
      |
      |        "business": {
      |          "content": [
      |            {
      |              "content": "car"
      |            },
      |            {
      |              "content": "bike"
      |            }
      |          ]
      |        }
      |
      |      }
      |    }
      |  }
      |}""".stripMargin

function to iterate complex json for give key list and get inner json value.

def getValue(input: Map[String, Any], keys: List[String]): Any = keys match {
    case lastKey :: Nil => input(lastKey)
    case key :: _ => getValue(input(key).asInstanceOf[JSONObject].obj, keys.tail)
  }

finally parse the json and get the output:

JSON.parseRaw(jsonString) match {
    case Some(jsonVal) =>
      println(jsonVal)
      val jsonMapKeyValuePair: Map[String, Any] =
        jsonVal.asInstanceOf[JSONObject].obj
      val keys = List("root", "datag", "content", "business", "content")
      val output: List[Any] =
        getValue(jsonMapKeyValuePair, keys)
          .asInstanceOf[JSONArray]
          .list
          .map(_.asInstanceOf[JSONObject].obj)
          .map(_.get("content").get)
      println(output)
    case _ =>
      println("Invalid Json Object.")
  }

Upvotes: 0

Related Questions