1. 「名稱/值」對的集合json
{ key-name : key-value }
- key-name: 類型只能是string - key-value: 類型多是number, string, boo, null, object, array
2. 值的有序列表, 在大多數狀況下能夠理解爲數組(Array)數組
[object, object, ...]
class JsonParser extends JavaTokenParsers { def jNum: Parser[Double] = floatingPointNumber ^^ (_.toDouble) def jStr: Parser[String] = stringLiteral ^^ (s => s.substring(1, s.length() - 1)) def jBool: Parser[Boolean] = "(true|false)".r ^^ (_.toBoolean) def jNull: Parser[Null] = "null".r ^^ (t => null) def term = jsonArray | jsonObject | jNum | jBool | jNull | jStr def jsonArray: Parser[List[Any]] = "[" ~> rep(term <~ ",?".r) <~ "]" ^^ (l => l) def jsonObject: Parser[Map[String,Any]] = "{" ~> rep( ( jStr ~ ":" ~ jNum | jStr ~ ":" ~ jBool | jStr ~ ":" ~ jNull | jStr ~ ":" ~ jsonObject | jStr ~ ":" ~ jsonArray | jStr ~ ":" ~ jStr ) <~ ",?".r ) <~ "}" ^^ { os => var map = Map[String,Any]() os.foreach(o => o match { case k ~ ":" ~ v => map = map ++ Map(k->v) }) map } }
這個 parser看上去仍是至關簡單的, 咱們來測試下功能app
val json = """{ | "key":"yardville", | "doc_count":2, | "avg_age":{ | "value":37.0 | }, | "count":{ | "value":2 | } |} """.stripMargin val jsonObject = JsonParser.parse(JsonParser.jsonObject,json) val result = jsonObject.get("key") println(result)
執行結果以下:工具
result is: yardville測試
從上面看來, 若是我對JSON對象訪問路徑是:count/value, 或者層次比較深, 如:A/B/C/D/E, 操做起來不太方便, 若是可以像下面這樣操做, 生活是否是太美好了!!! 好比:this
jsonObject.get("count").get("value").asIntscala
讓咱們來先建立JsonObject類rest
class JsonObject(value:Any) { def isJsonObject = { this.value.isInstanceOf[Map[String,Any]] } def asJsonObject = { if(isJsonObject) { this.value.asInstanceOf[Map[String,Any]] } else { throw new ClassCastException(s"it is not json object") } } def getJsonObject(key:String) = { new JsonObject(this.asJsonObject.get(key).get) } def get(key:String) = { new JsonElement(this.asJsonObject.get(key).get) } }
這時候咱們完成了無限級的getcode
jsonObject.getJsonObject("A").getJsonObject("B")...對象
當須要取葉子結點的值時
jsonObject.getJsonObject("A").getJsonObject("B").get("C").asString
咱們來看看JsonElement的實現
class JsonElement(value:Any) { def isObject = { this.value.isInstanceOf[Object] } def asObject = { if(isObject) { this.value.asInstanceOf[Object] } else { null } } def asString = { if(asObject!=null) asObject.toString else { "" } } def isDoubel = { this.value.isInstanceOf[Double] } def asDouble = { if(isDoubel) { this.value.asInstanceOf[Double] } else { 0d } } def isBoolean = { this.value.isInstanceOf[Boolean] } def asBoolean = { if(isBoolean) { this.value.asInstanceOf[Boolean] } else { false } } }
咱們還須要一個入口類 JsonMapper
class JsonMapper (text:String) { def getJsonObject(key:String) = { val result = JsonParser.parseAll(JsonParser.jsonObject,text) val eleMap = result.get new JsonObject(eleMap.get(key).get) } def getJsonArray(text:String) = { JsonParser.parseAll(JsonParser.jsonArray,text).get.map(l=>{ new JsonObject(l) }) } }
val dataMapping: String = """ { "temp": { "properties": { "temp": { "type": "string", "store": true } } } }""" val mapper = new JsonMapper(dataMapping) val jsonObject = mapper.getJsonObject("temp") val temp = jsonObject.getJsonObject("properties").getJsonObject("temp") val type_string = temp.get("type").asString val store = temp.get("store").asObject println(s"type:$type_string") println(s"store:$store")
結果以下:
type:string
store:true
val dataMappping = """[ | {"key":"yardville","doc_count":2,"avg_age":{"value":37.0},"count":{"value":2}}, | {"key":"camino","doc_count":1,"avg_age":{"value":37.0},"count":{"value":1}}, | {"key":"delshire","doc_count":1,"avg_age":{"value":36.0},"count":{"value":1}}, | {"key":"forestburg","doc_count":1,"avg_age":{"value":37.0},"count":{"value":1}}, | {"key":"foscoe","doc_count":1,"avg_age":{"value":31.0},"count":{"value":1}} |] """.stripMargin val mapper = new JsonMapper(dataMappping) val array = mapper.getJsonArray(dataMappping) val first = array(0) val key = first.get("key").asString val age_value = first.getJsonObject("avg_age").get("value").asObject val count_value = first.getJsonObject("count").get("value").asDouble.toInt println(s"key: $key") println(s"age avg: $age_value") println(s"count: $count_value")
結果以下:
key: yardville
age avg: 37.0
count: 2
到些爲止, 咱們沒有依賴任何JSON序列化工具, 完成的JSON string的讀取.