Проблема извлечения рекурсивных структур данных в scala с помощью json4s
У меня есть формат JSON, который состоит из карты -> карта -> ... -> 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 ответ
По умолчанию дерево, подобное вашему, расширено до другого 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)))))))