Kann ich die Scala Lift-json-Bibliothek verwenden, um einen JSON in eine Karte zu analysieren?

StackOverflow https://stackoverflow.com/questions/3843000

  •  27-09-2019
  •  | 
  •  

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.

War es hilfreich?

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])
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top