Parsing and manipulating json in Scala

Stefan Konno picture Stefan Konno · Jan 13, 2015 · Viewed 7.8k times · Source

I have this JSON that is returned from a REST-service I'm using.

{
    "id": "6804",
    "signatories": [
        {
            "id": "12125",
            "fields": [
                {
                    "type": "standard",
                    "name": "fstname",
                    "value": "John"
                },
                {
                    "type": "standard",
                    "name": "sndname",
                    "value": "Doe"
                },
                {
                    "type": "standard",
                    "name": "email",
                    "value": "[email protected]"
                },
                {
                    "type": "standard",
                    "name": "sigco",
                    "value": "Company"
                }
            ]
        }
    ]
}

Currently I'm looking into a way to parse this with json4s, iterating over the "fields" array, to be able to change the property "value" of the different objects in there. So far I've tried a few json libs and ended up with json4s.

Json4s allows me to parse the json into a JObject, which I can try extract the "fields" array from.

    import org.json4s._
    import org.json4s.native.JsonMethods._

    // parse to JObject
    val data = parse(json)

    // extract the fields into a map
    val fields = data \ "signatories" \ "fields"

    // parse back to JSON
    println(compact(render(fields)))

I've managed to extract a Map like this, and rendered it back to JSON again. What I can't figure out though is, how to loop through these fields and change the property "value" in them?

I've read the json4s documentation but I'm very new to both Scala and it's syntax so I'm having a difficult time.

The question becomes, how do I iterate over a parsed JSON result, to change the property "value"?

Here's the flow I want to achieve.

  1. Parse JSON into iterable object
  2. Loop through and look for certain "names" and change their value, for example fstname, from John to some other name.
  3. Parse it back to JSON, so I can send the new JSON with the updated values back.

I don't know if this is the best way to do this at all, I'd really appreciate input, maybe there's an easier way to do this.

Thanks in advance, Best regards,

Stefan Konno

Answer

mohit picture mohit · Jan 13, 2015

You can convert the json into an array of case class which is the easiest thing to do. For example: you can have case class for Fields like

case class Field(`type`: String, name: String, value: String)

and you can convert your json into array of fields like read[Array[Field]](json) where json is

 [
            {
                "type": "standard",
                "name": "fstname",
                "value": "John"
            },
            ...
        ]

which will give you an array of fields. Similarly, you can model for your entire Json.

As now you have an array of case classes, its pretty simple to iterate the objects and change the value using case classes copy method.

After that, to convert the array of objects into Json, you can simply use write(objects) (read and write functions of Json4s are available in org.json4s.native.Serialization package.

Update 

To do it without converting it into case class, you can use transformField function

parse(json).transformField{case JField(x, v) if x == "value" && v == JString("Company")=> JField("value1",JString("Company1"))}