I'm using json4s library in my project to manually parse JSON field by field (without automatic deserializing it to case classes).
For example I have following JSON:
{
result: "OK",
persons: [
{name: "Alex"},
{name: null}
]
}
And the official guide suggest to use this approach to manually parse it:
for {
JArray(persons) <- json / "persons"
JObject(person) <- persons
JField("name", JString(name)) <- person
} yield Person(name)
The problem is that this for-comprehension skips persons which has null
names. I think this is because in for-comprehension I used JString(name)
, so it expects some String
value, not a null
.
Is there any way to solve this? I just want to iterate over array and visit every object (even if it has null
instead some String
)
Yeah, you've already got the reason it can't work, you just have to change the pattern match like the following.
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
}
}
Actually, there is another simpler way following the Extracting values part in the documentation you mentioned.
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)