2012-01-05 121 views
1

这可能是一件容易的事情,而我的困难很可能是由于我对Scala的新颖性(它已经很快成为我最喜欢的语言)所致。从Scala中使用lift-json解析JSON呈现JSON

基本上我有一些JSON,看起来像这样:

{ 
"to"  : "Peter", 
"from" : "Dave", 
"bundle" : [ 
      {"data": [1,2,3,4,5]}, 
      {"data": [2,3,4,5,6]} 
      ] 

} 

现在,我已经解析了JSON的地步,我可以从标题提取数据(往返),并可以查看包中的单个消息。目前我使用的是这样的:

val messages = parsedJSON \\ "bundle" \\ classOf[JObject] 

for (m <- messages) println(m) 

这给了我:

Map(data -> List(1, 2, 3, 4, 5)) 
Map(data -> List(2, 3, 4, 5, 6)) 

但我想在这环做的就是把每一个地图,并将其转换回JSON即:

{ 
"data": [1,2,3,4,5] 
} 

我试过渲染(米)和各种其他半随机的东西来尝试并得到它的工作,但迄今没有骰子。最近我来给我这个错误:

No implicit view available from Any => net.liftweb.json.package.JValue. 

任何人都可以请指点我在正确的方向吗?

在此先感谢!

回答

3

我认为处理这个问题的最简单方法是为一个包创建一个case类。然后,Lift-json可以很好地将数据提取到实例中。然后,您可以循环遍历它们,并通过创建2元组来隐式地将它们转换回JObjects。

case class Bundle(data: List[BigInt]) 

val bundles = (parsedJSON \\ "bundle").extract[List[Bundle]] 
// List(Bundle(List(1, 2, 3, 4, 5)), Bundle(List(2, 3, 4, 5, 6))) 
bundles 
    .map{ bundle => ("data" -> bundle.data)} 
    .foreach{ j => println(compact(render(j)))} 
//{"data":[1,2,3,4,5]} 
//{"data":[2,3,4,5,6]} 
+0

不幸的是,捆绑中的单个消息的内容可以是任何有效的JSON,我不会提前知道。目前我只需要将每条消息中的数据保存到数据库中,但为了方便,我首先需要将消息作为简单的Scala(即地图和列表),以便将其交给数据库存储... – PeterM 2012-01-05 08:10:13

+0

是重新呈现的JSON进入数据库,还是你需要它解析为scala列表和映射到数据库?如果您实际上不需要列表/地图,则可以绕过整个过程并直接使用JValues。 – 2012-01-05 16:30:19

+0

最后,我只是用它“按原样”,但很遗憾,访问数据是非常fiddly :) – PeterM 2012-01-06 08:58:11

1

如果消息可以是任何数据,您可以将这些数据提取为JValues。

import net.liftweb.json._ 
import net.liftweb.json.JsonDSL._ 

val parsedJSON = parse(...) 
val bundles = (parsedJSON \\ "bundle").extract[List[JValue]] 
compact(render(bundles))