我可以使用Scala lift-json库将JSON解析为Map吗?

时间:2010-10-01 20:56:48

标签: json scala lift

有没有办法使用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模式。

2 个答案:

答案 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])