I'm new to Scala and I'm trying to process json document. I'm using scala 2.13.3 with the following librairies :
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.0" % "test"
libraryDependencies += "org.json4s" %% "json4s-native" % "3.6.9"
The problem is that I can't find a way to remove a key and still keep his children as follows:
Here's the json document to begin with:
{
"Key": {
"opt": {
"attribute1": 0,
"attribute2": 1,
"attribute3": 2
},
"args": {
"arg1": 0,
"arg2": 1,
"arg3": 2
}
}
}
I would like to remove the "Key"
to keep only his children "opt"
and "args"
so that I get the Json document below :
{
"opt": {
"attribute1": 0,
"attribute2": 1,
"attribute3": 2
},
"args": {
"arg1": 0,
"arg2": 1,
"arg3": 2
}
}
I use the Json4s
library to manipulate documents, there is a transformField
operator that allows to perform operations on fields (key, value) => (key, value)
. So I tried to define an empty key ""
but it doesn't answer my need. I also tried to return only the associated value but the partial function doesn't allow it.
Here is my scala code :
val json: JObject =
"Key" -> (
"opt" -> (
("attribute1" -> 0) ~
("attribute2" -> 1) ~
("attribute3" -> 2)
) ~
("args" -> (
("arg1", 0) ~
("arg2", 1) ~
("arg3", 2)
)))
val res = json transformField {
case JField("Key", attr) => attr
}
println(pretty(render(res)))
unfortunatly I can't just use transformField
to transform ("Key", attr)
into attr
.
Is there an easy way to remove the "Key"
key from my Json while keeping its children "opt"
and "args"
?
It is usually better to convert JSON to Scala objects, manipulate the Scala objects, and then convert back to JSON.
This is what it might look like using jackson
:
import org.json4s.{DefaultFormats, Extraction}
import org.json4s.jackson.{JsonMethods, Serialization}
val jsonIn = """
{
"Key": {
"opt": {
"attribute1": 0,
"attribute2": 1,
"attribute3": 2
},
"args": {
"arg1": 0,
"arg2": 1,
"arg3": 2
}
}
}
"""
case class Opt(attribute1: Int, attribute2: Int, attribute3: Int)
case class Args(arg1: Int, arg2: Int, arg3: Int)
case class Key(opt: Opt, args: Args)
case class DataIn(Key: Key)
implicit val formats = DefaultFormats
val dataIn: DataIn = Extraction.extract[DataIn](JsonMethods.parse(jsonIn))
val jsonOut: String = Serialization.write(dataIn.Key)
In this case the Scala processing is just extracting the Key
field from the DataIn
class.
I am on Scala 2.12 so YMMV.