2014-12-03 44 views
0

我試圖解析來自GovTrack的數據,例如https://www.govtrack.us/api/v2/bill/74369。但titles處於特有格式:使用JSON組合器解析複雜的JSON

"titles": [ 
[ 
    "short", 
    "introduced", 
    "Public Online Information Act of 2011" 
], 
[ 
    "official", 
    "introduced", 
    "To establish an advisory committee to issue nonbinding governmentwide guidelines..." 
] 

]

titles是每個標題類型的數組,與以特定的順序字段。我想讀入一個更標準的JSON格式如下:

{ 
    'short_title': "Public Online Information Act of 2011", 
    'official_title': "To establish an advisory committee to issue nonbinding governmentwide guidelines..." 
} 

的簡稱或官方名稱可能會或可能不會存在,並有可能實際上是幾個短標題。

如何爲此製作Reads?現在我得到了:

implicit val billReads: Reads[Bill] = (
    (JsPath \ "id").read[Int] and 
    (JsPath \ "display_number").read[String] and 
    (JsPath \ "current_status").read[String] and 
    (JsPath \ "titles")(0)(2).read[String] 
)(Bill.apply _) 

如何指定「具有第一個元素等於'官方'的數組的成員」?

+0

你能具體談談格式?你的例子不清楚。 – Ryan 2014-12-03 02:41:50

回答

1

據我所知,目前還沒有現成的方式做到這一點,但我會用另外的定製閱讀器做到這一點,就像這樣:

val officialReads = new Reads[String] { 
    override def reads(json: JsValue): JsResult[String] = (json \ "titles") match { 
    case JsArray(titles) => titles.collectFirst({ 
     case JsArray(values) if (values.headOption.map(v => "official".equals(v.as[String])).getOrElse(false)) => 
     JsSuccess(values.tail.tail.head.as[String]) 
    }).getOrElse(JsError("No official title")) 
    case _ => JsError("Can't read official title") 
    } 
} 

而且你的比爾的讀者應該是這樣的:

val implicitReads: Reads[Bill] = (
    (__ \ "id").read[Int] and 
    (__ \ "display_number").read[String] and 
    (__ \ "current_status").read[String] and 
    officialReads 
    )(Bill.apply _) 

我測試過,這個工作:)