burk
burk

Reputation: 355

Removing top level field in json4s when nested field with similar name exists

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

Answers (3)

cstroe
cstroe

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

Aditya Chadha
Aditya Chadha

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

nmat
nmat

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

Related Questions