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

tom*_*eng 12 json scala lift

有没有办法使用lift-json库的JObject类来表现得像Map?

例如:

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>
Run Code Online (Sandbox Code Playgroud)

我原本期望记录("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")

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")

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模式.

Ale*_*nov 13

如果你看一下实现,你会看到

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
}
Run Code Online (Sandbox Code Playgroud)

所以这应该工作:

record.values.asInstanceOf[Map[String, Any]]("foo")
Run Code Online (Sandbox Code Playgroud)

你也可以试试

record.values.apply("foo")
Run Code Online (Sandbox Code Playgroud)


Jon*_*oni 7

JValue.Values是一种路径依赖类型.这意味着如果你持有JString它将是一个String,或者如果你有一个JArray它将是一个List [Any].如果您确定要解析的JSON是JSON对象,则可以将其强制转换为正确的类型.

val record = JsonParser.parse(json).asInstanceOf[JObject]
Run Code Online (Sandbox Code Playgroud)

JObject的路径依赖类型是Map [String,Any],因此:

scala> record.values("foo")                                     
res0: Any = bar
Run Code Online (Sandbox Code Playgroud)

只是好奇,如果您不知道要解析的数据的形状,是不是有点问题?

请注意,如果您的数据包含(名称,描述,年龄)且年龄是可选的,您可以将该JSON读入:

case class Person(name: String, description: String, age: Option[Int])
Run Code Online (Sandbox Code Playgroud)