2014-06-21 7 views
5

Prendere in considerazione il seguente JSON fornito da un fornitore API:Come attraversare i campi oggetto JSON usando JsPath?

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) 

Come estrarre una sequenza di coppie correlate a "etichetta" e campi "id". Da questo pezzo di JSON il risultato che mi aspetto è:

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

sto in mancanza, con la costruzione di una corretta estrattore JsPath perché si aspetta una partita di esempio

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

risposta

3

Ecco come avrei creato questo parser con bei brani componibili. Prima per un uso generale oggetto-to-array trasformatore che butta via tasti:

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

Ora per un Reads in grado di elaborare gli oggetti mercato:

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

E ora legare tutto insieme:

val pairsReads: Reads[List[(Int, String)]] = 
    (__ \ 'returns \ 'markets).read(objToArray) andThen list(marketReads) 

E infine:

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

Quale è quello che vuoi. Nota che ho specificato i tipi sopra per chiarezza, ma non è necessario qui - probabilmente li lascerei in codice reale perché i pezzi sono piuttosto piccoli e diretti.

+0

Questo è esattamente quello che stavo cercando. Praticamente la prima istruzione è qualcosa che non ho potuto trovare. –

+0

That 'objToArray' è superclea. Grazie! –

Problemi correlati