问题
Is there a way to use the lift-json library's JObject class to act like a Map?
For example:
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>
I would have expected record("foo") to return "bar"
I noticed a values function and it prints out a Map but the actual object is a 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")
There are examples with the lift-json library extracting a case class but in this case, I don't know the json schema in advance.
回答1:
If you look at the implementation, you'll see
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
}
So this should work:
record.values.asInstanceOf[Map[String, Any]]("foo")
You could also try
record.values.apply("foo")
回答2:
JValue.Values is a path dependent type. Meaning that if you hold on a JString it will be a String, or if you got a JArray it will be a List[Any]. If you are sure that the JSON you parse is a JSON object you can cast it to a proper type.
val record = JsonParser.parse(json).asInstanceOf[JObject]
A path dependent type for JObject is a Map[String, Any], thus:
scala> record.values("foo")
res0: Any = bar
Just of curiosity, isn't it a bit problematic if you do not know the shape of data you are going to parse?
Note, if your data contains (name, description, age) and the age is optional you can read that JSON into:
case class Person(name: String, description: String, age: Option[Int])
来源:https://stackoverflow.com/questions/3843000/can-i-use-the-scala-lift-json-library-to-parse-a-json-into-a-map