Kann ich die Scala Lift-json-Bibliothek verwenden, um einen JSON in eine Karte zu analysieren?
Frage
Gibt es eine Möglichkeit, die Hochauftriebs json Bibliothek JObject Klasse zu verwenden wie eine Karte zu handeln?
Zum Beispiel:
val json = """
{ "_id" : { "$oid" : "4ca63596ae65a71dd376938e"} , "foo" : "bar" , "size" : 5}
"""
val record = JsonParser.parse(json)
record: net.liftweb.json.JsonAST.JValue = JObject(List(JField(_id,JObject(List(JField($oid,JString(4ca63596ae65a71dd376938e))))), JField(foo,JString(bar)), JField(size,JInt(5))))
</code>
Ich hätte Datensatz ( "foo") zu erwarten zurückzukehren "bar"
Ich habe bemerkt, a-Werte funktionieren und es gibt eine Karte, aber das eigentliche Objekt ist ein JValue.this.Values?
scala> record.values
res43: record.Values = Map((_id,Map($oid -> 4ca63596ae65a71dd376938e)), (foo,bar), (size,5))
scala> record.values("foo")
:12: error: record.values of type record.Values does not take parameters
record.values("foo")
Es gibt Beispiele mit der Lift-json Bibliothek eine Fallklasse Extrahieren aber in diesem Fall, ich weiß nicht, das json Schema im Voraus.
Lösung
Wenn Sie bei der Umsetzung anschauen, werden Sie sehen
case class JObject(obj: List[JField]) extends JValue {
type Values = Map[String, Any]
def values = Map() ++ obj.map(_.values.asInstanceOf[(String, Any)]) // FIXME compiler fails if cast is removed
}
Also das sollte funktionieren:
record.values.asInstanceOf[Map[String, Any]]("foo")
Sie können auch versuchen,
record.values.apply("foo")
Andere Tipps
JValue.Values ??ist ein Weg abhängiger Typ. Was bedeutet, dass, wenn Sie auf einem JString halten wird es ein String sein, oder wenn Sie einen JArray bekommen es wird eine Liste [Alle] sein. Wenn Sie sicher sind, dass die JSON Sie Parse ist ein JSON-Objekt Sie es zu einem richtigen Typ umwandeln kann.
val record = JsonParser.parse(json).asInstanceOf[JObject]
Ein Pfad abhängiger Typ für JObject ist eine Map [String, Alles], also:
scala> record.values("foo")
res0: Any = bar
Nur aus Neugier, ist es nicht ein bisschen problematisch, wenn Sie die Form der Daten nicht kennen Sie Parse werden?
Beachten Sie, wenn Sie Ihre Daten (Name, Beschreibung, Alter) und das Alter ist optional können Sie lesen, dass JSON in:
case class Person(name: String, description: String, age: Option[Int])