有没有办法使用lift-json库的JObject类来表现地图?
例如:
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>
我希望记录(“foo”)能够返回“bar”
我注意到了一个值函数,它打印出一个Map,但实际的对象是一个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")
有一些示例,其中lift-json库提取了一个case类,但在这种情况下,我事先并不知道json模式。
答案 0 :(得分:12)
如果你看一下实现,你会看到
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
}
所以这应该有效:
record.values.asInstanceOf[Map[String, Any]]("foo")
您也可以尝试
record.values.apply("foo")
答案 1 :(得分:7)
JValue.Values是一种路径依赖类型。这意味着如果你持有JString它将是一个String,或者如果你有一个JArray它将是一个List [Any]。如果您确定要解析的JSON是JSON对象,则可以将其转换为正确的类型。
val record = JsonParser.parse(json).asInstanceOf[JObject]
JObject的路径依赖类型是Map [String,Any],因此:
scala> record.values("foo")
res0: Any = bar
只是好奇,如果您不知道要解析的数据的形状,是不是有点问题?
注意,如果您的数据包含(名称,描述,年龄)且年龄是可选的,您可以将该JSON读入:
case class Person(name: String, description: String, age: Option[Int])