2015-09-06 111 views
2

我在我的項目中使用json4s庫手動解析JSON字段的字段(沒有自動反序列化到案例類)。使用json4s解析JSON中的空值

,比如我有以下JSON:

{ 
    result: "OK", 
    persons: [ 
    {name: "Alex"}, 
    {name: null} 
    ] 
} 

而且官方指南建議使用這種方法來手動解析它:

for { 
     JArray(persons) <- json/"persons" 
     JObject(person) <- persons 
     JField("name", JString(name)) <- person 
     } yield Person(name) 

的問題是,這種換理解跳過的人哪有null名稱。我認爲這是因爲在理解中我使用了JString(name),所以它需要一些String值,而不是null

有什麼辦法解決這個問題嗎?我只是想遍歷數組並訪問每個對象(即使它有null而不是一些String

回答

2

是的,你已經有了它不能工作的原因,你只需要改變模式匹配以下。

case class Person(name: String) 
// the result is actually List[Option[Person]] 
val result = 
    for { 
    JArray(persons) <- json \ "persons" 
    JObject(person) <- persons 
    // jv is JsonAST.JValue 
    JField("name", jv) <- person 
    } yield { 
    // in case of match error so add _ here 
    jv match { 
     case JString(name) => Some(Person(name)) 
     case JNull => Some(Person(null)) 
     case _ => None 
    } 
    } 

其實,有以下你提到的文檔中的部分Extracting values另一種更簡單的方法。

case class Person(name: String) 
import org.json4s.DefaultFormats 
implicit val formats = DefaultFormats // Brings in default date formats etc 
val result2 = (json \ "persons").extract[List[Person]] 
// List(Person(Alex), Person(null)) 
println(result2) 
+0

可以請你的答案複製到這個問題:http://stackoverflow.com/questions/25200005/extract-options-from-potentially-null-json -values-using-for表達式 我在那裏打開賞金 – MyTitle

+0

我可以這麼做,但認真的說我不認爲這是值得你爲回答「支付」300名聲譽。 –

+0

也想問:我的JSON的每個字段可能都是空的,而且我有大約15個我感興趣的字段,所以我似乎需要用這種模式匹配來替換每個字段提取(5行而不是1行)的代碼)。有比模式匹配更緊湊的方式嗎? 第二種方法不適合我(我在創建案例類之前進行了很多提取字段的轉換) – MyTitle

0

這樣做,

val r:List[Person] = for { 
    JArray(persons) <- JsonMethods.parse(json) \ "persons" 
    JObject(person) <- persons 
    //JField("name", JString(name)) <- person 
    p = Person(person.head._2) //or Person(person.find(_._1=="name").map(_._2).getOrElse(null)) 
    } yield p 

    println(r) //List(Person("Alex"), Person(null))