0

In Scala, how can I de-serialize a JSON string, modify a value and serialize back to string?

There has to be a way to do this without using 3rd party libraries but I can't get it to work. Here is what I tried so far:

import scala.util.parsing.json

var lines = "{\"id\" : \"abc\", \"stuff\" : [1, 2, 3], \"more\" : {\"bro\" : \"science\"}}"

// Test 1
val myJSON = json.JSON.parseRaw(lines)
// myJSON: Option[scala.util.parsing.json.JSONType] = Some({"id" : "abc", "stuff" : [1.0, 2.0, 3.0], "more" : {"bro" : "science"}})
// I cannot modify fields on the JSONType instance but toString() works well.
// res1: String = Some({"id" : "abc", "stuff" : [1.0, 2.0, 3.0], "more" : {"bro" : "science"}})

// Test 2
// This way I can parse JSON into a map and manipulate its values.
// val myMap = json.JSON.parseFull(lines).get.asInstanceOf[Map[String, Any]] + ("id" -> "blah")
// myMap: scala.collection.immutable.Map[String,Any] = Map(id -> blah, stuff -> List(1.0, 2.0, 3.0), more -> Map(bro -> science))

// However, when converted to an instance of JSONObject and calling
// toString() only the top-level items are JSON-serialized
new json.JSONObject(myMap).toString()
// res2: String = {"id" : "blah", "stuff" : List(1.0, 2.0, 3.0), "more" : Map(bro -> science)}

If it's not possible with standard Scala, I'd appreciate and example of how to do this with a third party library.

Thanks,

/David

4
  • 1
    Possible duplicate of stackoverflow.com/questions/4170949/…, though nowadays the JSON parser with parser combinators seems to be deprecated (too slow, unmaintained). Looking for alternatives: softwarerecs.stackexchange.com. Commented Feb 9, 2015 at 12:24
  • 5
    There are many JSON libs (e.g. Argonaut, Play-Json, Lift-Json, ...) Commented Feb 9, 2015 at 12:41
  • Ive been using github.com/json4s/json4s with some success. It has a nice API. Commented Feb 9, 2015 at 14:06
  • Play JSON has JSON transformers which will accomplish this. Commented Feb 9, 2015 at 14:22

1 Answer 1

1

small silly/trivial example of what I mentioned. Could be written better too but wanted to break it into chunks. There is a lot you can do with them:

Here is old link in terms of play version but as far as I know up to date on features available in 2.3.x:

https://www.playframework.com/documentation/2.1.1/ScalaJsonTransformers

import play.api.libs.json._

var lines = "{\"id\" : \"abc\", \"stuff\" : [1, 2, 3], \"more\" : {\"bro\" :        \"science\"}}"

val jsonAsJsValue = Json.parse(lines)
//jsonAsJsValue: play.api.libs.json.JsValue = {"id":"abc","stuff":    [1,2,3],"more":{"bro":"science"}}
val updateIdTransformer =  (__ \"id").json.update(
 __.read[JsString].map{a => JsString("def")}
)

val updatedJson = jsonAsJsValue.transform(updateIdTransformer)

//updatedJson: play.api.libs.json.JsResult[play.api.libs.json.JsObject] =    JsSuccess({"id":"def","stuff":[1,2,3],"more":{"bro":"science"}},/id)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.