Scala Play - 迭代JsArray / JsObject以检索键并计算值为null的键的出现次数

时间:2018-05-24 00:27:22

标签: json scala playframework

我正在使用Play JSON库来验证JSON模式。 我有以下JSON data。我需要验证这个JSON的模式。

// Scala Code
package com.base

import scala.io.Source
import play.api.libs.json._
import play.api.libs.json.JsNull
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._

import com.utils.ReadJsonFile._

case class JsValueToModel(web_pages: Array[String], name: String, alpha_two_code: String , state_province: Option[String], domains: Array[String], country: String)

object ValidateJSON extends App {

// Parsing Json file to JsArray
val json = Json.parse(readJson1)    

// Using Recursive path by each key to traverse json
val web_pages = json \\ "web_pages" 
val name = json \\ "name" 
val alpha_two_code = json \\ "alpha_two_code"
val state_province = json \\ "state-province"
val domains = json \\ "domains"
val country = json \\ "country" 

// Converting JsValue to Model to read the json key value
implicit val JsValueToModelReads: Reads[JsValueToModel] = (
    (JsPath \ "web_pages").read[Array[String]] and
    (JsPath \ "name").read[String] and
    (JsPath \ "alpha_two_code").read[String] and
    (JsPath \ "state-province").readNullable[String] and
    (JsPath \ "domains").read[Array[String]] and
    (JsPath \ "country").read[String]
)(JsValueToModel.apply _)   


// Validation Json Object with JsonSchemaModel  
val validateJson = json.validate[List[JsValueToModel]] match {
    case s: JsSuccess[List[JsValueToModel]] => {
        // val v: List[JsValueToModel] = s.get  
        println("Validation Success")
    }
    case e: JsError => {
        println("Validation Errors: " + JsError.toJson(e).toString)
    }
}   
// Length of json
println(json.as[JsArray].value.size)

我收到以下错误 -

json.as[JsObject].map((a,b) => (a == null))

value map is not a member of play.api.libs.json.JsObject [error] json.as[JsObject].map((a,b) => (a == null))

json.map((a,b) => (a == null))

value map is not a member of play.api.libs.json.JsValue [error] json.map((a,b) => (a == null))

我不知道该改变什么。我尝试做一些模式匹配但不能做 - 比如 -

def findAndCountNull(a: JsValue):(String,Option[Any]) = a match {
    case (x,y) => (x == null) // ???
    case _ => a
}

感谢您对此有所帮助。 我看了一些其他的库,比如json4s,JsZipper以及电梯,但是想用play json库来理解。

1 个答案:

答案 0 :(得分:2)

使用JSON automated mapping

    import play.api.libs.json.{JsError, JsSuccess, Json}

    import scala.io.{Codec, Source}

    object Data {
      implicit val jsonFormat = Json.format[Data]
    }

    case class Data(web_pages: Seq[String], name: String, alpha_two_code: String, `state-province`: Option[String], domains: Seq[String], country: String)

    val str = Source.fromURL("https://raw.githubusercontent.com/Hipo/university-domains-list/master/world_universities_and_domains.json")(Codec.UTF8).mkString

Json.parse(str).validate[Seq[Data]] match {
     case JsSuccess(x, _) =>
         Right(x)
     case JsError(errors) =>
         Left(errors)
    }

结果:

    res0: scala.util.Either[Seq[(play.api.libs.json.JsPath, Seq[play.api.libs.json.JsonValidationError])],Seq[Data]] =
 Right(List(Data(List(https://www.cstj.qc.ca, https://ccmt.cstj.qc.ca, https://ccml.cstj.qc.ca),Cégep de Saint-Jérôme,CA,None,List(cstj.qc.ca),Canada), Data(List(http://www.lindenwood.edu/),Lindenwood University,US,None,List(lindenwood.edu),United States), Data(List(http://www.davietjal.org/),DAV Institute of Engineering & Technology,IN,Some(Punjab),List(davietjal.org),India), Data(List(http://www.lpu.in/),Lovely Professional University,IN,Some(Punjab),List(lpu.in),India), Data(List(https://sullivan.edu/),Sullivan University,US,None,List(sullivan.edu),United States), Data(List(https://www.fscj.edu/),Florida State College at Jacksonville,US,None,List...

仅计算null - 使用模式匹配(简化 - 你也应该检查JSArray):

val parsed = Json.parse(str)
val seq = parsed.as[JsArray].value.map(_ \\ "state-province").map(x => x.head)
val nulls = seq.count {
    case JsNull => true
    case _ => false
  }

println(s"$nulls")