/ / Controlla se un oggetto ha un campo in json4s / lift-json - json, scala, lift-json, json4s

Controlla se un oggetto ha un campo in json4s / lift-json - json, scala, lift-json, json4s

Ho un json con alcuni campi e voglio controllare se alcuni di essi sono presenti. Sto estraendo il valore e testandolo contro JNothing, ma è troppo prolisso:

val json: JValue = ...

val jsonIsType1 = (json  "field1") != JNothing && (json  "field2") != JNothing

C'è un modo più compatto per verificare la presenza di un campo in un oggetto json usando json4s / lift-json? Idealmente qualcosa come:

val jsonIsType1 = json.has("field1") && json.has("field2")

risposte:

14 per risposta № 1

JValue non ha un operatore "ha", ma il potere degli impliciti di Scala ti consente di aggiungere quella funzionalità senza troppi problemi.

Ecco un esempio di questo:

implicit class JValueExtended(value: JValue) {
def has(childString: String): Boolean = {
if ((value  childString) != JNothing) {
true
} else {
false
}
}
}

Esempio di utilizzo:

scala> val json = Json.parse("""{"field1": "ok", "field2": "not ok"}""")

scala> json.has("field1")
res10: Boolean = true

2 per risposta № 2

È inoltre possibile combinare più passaggi di lettura / convalida all'interno di a per comprensione. Di seguito sono due funzioni, una che restituisce un Option[_] e uno che restituisce a Boolean. Il primo permette di lavorare anche con i dati, mentre il secondo solo la validazione.

import org.json4s.jackson.JsonMethods._

val text =
"""
|{
|  "foo": "bar",
|  "baz": "fnord",
|  "qux": true
|}
""".stripMargin

val json = parse(text)

def readFoo(x: JValue): Option[(String, String, Boolean)] = for {
JObject(_) <- x.toOption
JString(foo) <- (x  "foo").toOption
JString(baz) <- (x  "baz").toOption
JBool(qux) <- (x  "qux").toOption
if (qux == true)
} yield (foo, baz, qux)

def validateOnly(x: JValue): Boolean = (for {
JObject(_) <- x.toOption
JString(foo) <- (x  "foo").toOption
JString(baz) <- (x  "baz").toOption
JBool(qux) <- (x  "qux").toOption
if (qux == true)
} yield true) getOrElse false

println(readFoo(json))            // Some((bar,fnord,true))
println(readFoo(json).isDefined)  // true
println(validateOnly(json))       // true