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

发布于 2024-09-26 10:16:12 字数 804 浏览 4 评论 0原文

有没有办法使用 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>

我希望 record("foo") 返回“bar”

我注意到一个值函数,它打印出一个 Map 但实际对象是 JValue.this.Values?

<代码> 标量>记录值 res43: record.Values = Map((_id,Map($oid -> 4ca63596ae65a71dd376938e)), (foo,bar), (size,5))

scala>;记录.值(“foo”) :12: 错误: record.values 类型的 record.Values 不带参数 记录.值(“foo”)

有 lift-json 库提取案例类的示例,但在本例中,我事先不知道 json 模式。

Is there a way to use the lift-json library's JObject class to act like a Map?

For example:

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>

I would have expected record("foo") to return "bar"

I noticed a values function and it prints out a Map but the actual object is a 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")

There are examples with the lift-json library extracting a case class but in this case, I don't know the json schema in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡看悲欢离合 2024-10-03 10:16: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")

If you look at the implementation, you'll see

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
}

So this should work:

record.values.asInstanceOf[Map[String, Any]]("foo")

You could also try

record.values.apply("foo")
梦罢 2024-10-03 10:16:12

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

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

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

scala> record.values("foo")                                     
res0: Any = bar

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

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

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

JValue.Values is a path dependent type. Meaning that if you hold on a JString it will be a String, or if you got a JArray it will be a List[Any]. If you are sure that the JSON you parse is a JSON object you can cast it to a proper type.

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

A path dependent type for JObject is a Map[String, Any], thus:

scala> record.values("foo")                                     
res0: Any = bar

Just of curiosity, isn't it a bit problematic if you do not know the shape of data you are going to parse?

Note, if your data contains (name, description, age) and the age is optional you can read that JSON into:

case class Person(name: String, description: String, age: Option[Int])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文