使用json4s在scala中提取递归数据结构时遇到问题

时间:2014-10-06 20:29:46

标签: json scala json4s

我的json格式包含map - >地图 - > ... - > int表示每个键的任意数量的映射。键始终是字符串,叶类型始终是整数。地图结构的深度因地图中的每个键而异。例如,键“A”可以是Map [String,Int]类型,键“B”可以是Map [String,Map [String,Int]]类型。我知道我可以成功解析这种格式,如Map [String,Any],但我正在尝试保留类型,以便在代码中更容易合并这些结构。

我似乎无法定义我的嵌套结构,以免在json4s提取上抛出错误。我不太确定问题是在我的结构定义中,还是我没有正确地执行json提取。

这是代码

sealed trait NestedMap[A]
case class Elem[A](val e : A) extends NestedMap[A]
case class NMap[A](val e : Map[String, NestedMap[A]]) extends NestedMap[A]
// XXX this next line doesn't seem to help or hurt
case class Empty extends NestedMap[Nothing]

implicit val formats = DefaultFormats
val s = "{\"1\": 1, \"2\": 1, \"3\": {\"4\": 1}}"

val b = parse(s).extract[NMap[Int]] 

这是始终出现的错误

org.json4s.package$MappingException: No usable value for e
Expected object but got JNothing

我是否需要添加另一个扩展NestedMap的值?我完全错了吗?非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

默认情况下,像您这样的树会扩展为不同的json。

import org.json4s._
import org.json4s.native.Serialization
import org.json4s.native.Serialization.{read, write}
import org.json4s.native.JsonMethods._

implicit val formats = Serialization.formats(NoTypeHints)

sealed trait Elem
case class Leaf(val e:Int) extends Elem
case class Tree(val e:Map[String, Elem]) extends Elem

scala> val t = Tree(Map("1"->Leaf(1),"2"->Leaf(2),"3"->Tree(Map("4"->Leaf(4)))))
t: Tree = Tree(Map(1 -> Leaf(1), 2 -> Leaf(2), 3 -> Tree(Map(4 -> Leaf(4)))))
scala> write(t)
res0: String = {"e":{"1":{"e":1},"2":{"e":2},"3":{"e":{"4":{"e":4}}}}}
scala> val jt = parse(res0)
jt: org.json4s.JValue = JObject(List((e,JObject(List((1,JObject(List((e,JInt(1))))), (2,JObject(List((e,JInt(2))))), (3,JObject(List((e,JObject(List((4,JObject(List((e,JInt(4))))))))))))))))


scala> val s = """{"1":1,"2":2, "3":{"4":1}}"""
s: String = {"1":1,"2":2, "3":{"4":1}}
scala> val st = parse(s)
st: org.json4s.JValue = JObject(List((1,JInt(1)), (2,JInt(2)) (3,JObject(List((4,JInt(1)))))))