Reputation: 355
I would like to remove a top level field called "id" in a json structure, without removing all fields named "id", which happens when I run the following code:
scala> import org.json4s._
import org.json4s._
scala> import org.json4s.native.JsonMethods._
import org.json4s.native.JsonMethods._
scala> import org.json4s.JsonDSL._
import org.json4s.JsonDSL._
scala> val json = parse("""{ "id": "bep", "foo": { "id" : "bap" } }""")
json: org.json4s.JValue = JObject(List((id,JString(bep)), (foo,JObject(List((id,JString(bap)))))))
scala> json removeField {
| case ("id", v) => true
| case _ => false
| }
res0: org.json4s.JValue = JObject(List((foo,JObject(List()))))
Any idea how I can avoid removing the inner "id" field?
Edit: unfortunately I do not have the ability to list all the possible top level objects the json contains or can contain.
Upvotes: 2
Views: 2593
Reputation: 4236
It seems like removeField
applies to the entire JSON tree.
This works only for the top-level:
val updated = json match {
case JObject(l) => JObject(l.filter {
case (name, _) => name != "id"
})
}
Upvotes: 3
Reputation: 27
To do this without the need to know the schema of other fields:
JObject(
json.asInstanceOf[JObject].obj.filterNot(_._1 == "id")
)
JObject().obj is the flat list of fields that compose the object.
This doesn't seem possible staying within the json4s DSL though.
Upvotes: -1
Reputation: 7591
Based on the answer here you could do something like this:
val transformedJson2 = json transform {
case JField("id", _) => JNothing
case JField("foo", fields) => fields
}
It is definitely not ideal because you would have to specify all the foo
elements with a sub element id
Upvotes: -1