使用Scala的json4s

时间:2016-06-14 00:57:45

标签: json scala parsing json4s

给定解析(通过json4s)json字符串,例如以下org.json4s.JValue

val data: JValue = parse("""{
    "important_field" : "info",
    "some_junk" : 12345,
    "interesting_stuff" : {
        "pi" : 3.14,
        "e" : 2.72
    }
}""")

我可以有选择地提取我需要的信息:

case class Data(important_field: String) 
val extracted: Data = data.extract[Data]

给予extracted: Data = Data(info)。此外,我可以使用另一个案例类从嵌套的json对象中提取信息:

case class Stuff(pi: Double)
case class Data(important_field: String, interesting_stuff: Stuff)
val extracted: Data = data.extract[Data]

给了我extracted: Data = Data(info,Stuff(3.14))。但是现在,如果我想访问嵌套对象中的字段,我需要使用Stuff,我的内部案例类:

val pi: Double = extracted.interesting_stuff.pi

我更喜欢放弃嵌套,因此Data是平的,即我想要访问(原始)嵌套字段,如下所示:

val pi: Double = extracted.pi

在这个简单的例子中,使用嵌套类并不是那么痛苦,但是当存在多个嵌套级别时,必须在我的对象中维护嵌套是令人沮丧的。有没有一种典型的方法来处理这个?一些花哨的Scala技巧?

2 个答案:

答案 0 :(得分:2)

在将json内容映射到您自己的case类之前,可以转换嵌套的json结构:

CREATE FUNCTION [dbo].[F](@I1 INT,@I2 INT)
RETURNS INT
AS
BEGIN
RETURN @I1
END

GO
DECLARE @number INT =  2147483647
SELECT @number = number
FROM master..spt_values
WHERE number <  [dbo].[F](@number, number)
ORDER BY number

SELECT @number, @@ROWCOUNT

因此,不必定义嵌套的案例类object NestedJsonSpec { case class Data(important_field: String, pi: Double) implicit val formats = DefaultFormats // Brings in default date formats etc. def extract(source: JsonInput) : Data = { parse(source).transformField({ case JField("interesting_stuff", jv) => ("pi", jv \ "pi") }).extract[Data] } }

代码中使用的依赖项是:

Stuff

以下是与unit test相关的github项目。

答案 1 :(得分:1)

您可以在外部案例类

中定义到嵌套字段的getter
case class Data(important_field: String, interesting_stuff: Stuff) {
    def pi: Double = interesting_stuff.pi
}

// now you'll be able to write
val pi: Double = extracted.pi

缺点是您必须手动为您想要轻松访问的每个嵌套字段执行此操作