2014-06-21 11 views
5

Weźmy pod uwagę następujące JSON dostarczonego przez sprzedawcę API:Jak przechodzić przez pola obiektów JSON za pomocą 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) 

Jak wyodrębnić sekwencję par związanych z „label” i pola „id”. Od tego kawałka JSON roku wynik Czekam brzmi:

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

ja z braku prawidłowego konstruowania JsPath ściągacza ponieważ oczekuje ani jednego meczu na przykład

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

Odpowiedz

3

Oto jak zbudowałem ten parser z ładnych kompozycyjnych elementów. Po pierwsze dla ogólnego przeznaczenia transformatora obiekt-tablicy, która wyrzuca klawisze:

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

Teraz na Reads które mogą przetwarzać obiekty rynku:

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

A teraz wiążemy to wszystko razem:

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

I wreszcie:

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

To, czego chcesz. Zauważ, że podałem powyższe typy dla jasności, ale nie jest to konieczne - prawdopodobnie zostawiłbym je w prawdziwym kodzie, ponieważ elementy są dość małe i proste.

+0

To jest dokładnie to, czego szukałem. Praktycznie pierwsza instrukcja to coś, czego nie mogłem znaleźć. –

+0

To "objToArray" jest superclever. Dziękuję Ci! –

Powiązane problemy