2014-06-21 2 views
5

hesaba bir satıcı API tarafından sağlanan aşağıdaki JSON atın: JsPath kullanarak JSON nesne alanları nasıl geçilir?

import play.api.libs.json._ 
import play.api.libs.json.Reads._ 
import play.api.libs.functional.syntax._ 

val json = Json.parse(
    """ 
    |{ 
    | "returns": { 
    | "markets" : { 
    |  "ABC" : { 
    |  "label": "ABC", 
    |  "id":1 
    |  }, 
    |  "DEF" : { 
    |  "label": "DEF", 
    |  "id":2 
    |  } 
    | } 
    | } 
    |} 
    """.stripMargin) 

nasıl "Etiket" ve "id" alanları ile ilgili çiftlerinin bir dizilimi. Beklediğim JSON bu parça sonucu itibaren : Ben doğru JsPath çıkarıcı inşa ile başaramıyorum

Seq((1,"ABC"),(2,"DEF")) 

o mesela tek maç bekliyor çünkü

val jsonTransformer = (__ \ 'returns \ 'markets).json.pick 
json.transform(jsonTransformer) 

cevap

3

Bu ayrıştırıcıyı güzel bileşimli parçalardan nasıl yapılandıracağım.

val marketReads: Reads[(Int, String)] = 
    ((__ \ 'id).read[Int] and (__ \ 'label).read[String]).tupled 

Ve şimdi hep birlikte kravat: Piyasa nesneleri işleyebilir bir Reads Şimdi

val objToArray: Reads[JsArray] = 
    JsPath.json.pickBranch.map(obj => JsArray(obj.fields.map(_._2))) 

:

tuşları atıyor bir genel amaçlı nesne-dizi transformatör için ilk
val pairsReads: Reads[List[(Int, String)]] = 
    (__ \ 'returns \ 'markets).read(objToArray) andThen list(marketReads) 

Ve nihayet:

scala> json.validate(pairsReads).foreach(println) 
List((1,ABC), (2,DEF)) 

İstediğiniz hangisidir. Açıklamak için yukarıdaki türleri belirttiğime dikkat edin, fakat bu burada gerekli değil — muhtemelen onları gerçek kodda bırakırım çünkü parçalar oldukça küçük ve basittir.

+0

Tam olarak aradığım şey bu. Pratik olarak ilk talimat, bulamadığım bir şeydir. –

+0

Bu 'objToArray' süperdir. Teşekkür ederim! –