2010-10-01 98 views
11

有没有办法使用lift-json库的JObject类来像一个Map一样?我可以使用Scala lift-json库将JSON解析为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> 

我本来期望的记录(“富”)返回“巴”

我注意到一个值函数,它打印出地图,但实际的对象是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")

有与升降JSON库提取案例类的例子,但在这种情况下,我不知道提前JSON模式。

+0

这是一个case类解析地图作为参数相关答案http://stackoverflow.com/questions/5051290/deserializing-case-classes-with-mapstring-any-properties-with-lift-json/6310493#6310493 – 2011-06-10 18:57:33

回答

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

谢谢,第一个作品,第二个选择使用apply( )返回一个错误。我结束了使用scala的内置java解析器。 scala.util.parsing.json.JSON.parseFull(记录)将返回一些(地图)或一些(列表) – 2010-10-01 21:14:03

7

JValue.Values是路径依赖型。这意味着如果你持有一个JString,它将是一个字符串,或者如果你有一个JArray,它将是一个List [Any]。如果您确定您分析的JSON是JSON对象,则可以将其转换为适当的类型。

val record = JsonParser.parse(json).asInstanceOf[JObject] 

的路径依赖型的JObject是Map [字符串,任何],即:

的好奇心
scala> record.values("foo")          
res0: Any = bar 

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

请注意,如果您的数据包含(名称,描述,岁)和年龄是可选的,你可以阅读JSON到:

case class Person(name: String, description: String, age: Option[Int]) 
+0

我有一个json,它有一个不同的字段数组。例如。第一份文件可能有(姓名,描述,年龄),但第二份文件可能只有(姓名,年龄)指定。如果我使用scala的Map对象,我可以调用document.getOrElse(“foo”,“”) – 2010-10-01 21:25:59

相关问题