Convert JValue to String in Lift Scala - json

I have json string. I converted it to JValue using net.liftweb.JsonParser
val x : JValue = parse(json)
Then i modified the value of a field called "name" using replace()
x.replace("name" :: Nil, JString("Tim"))
Question is how do i convert this JValue back to a json String

You can simply use this
import net.liftweb.json._
compact(render(x))
Which will give you a json string version of the JValue object in this form
String = {"name":"Tim"}

In latest version 3.3.0 as of now in 2018 use below to convert from JsonAST.JValue to json string:
import net.liftweb.json._
compactRender(jValue)

Related

Scala - Couldn't remove double quotes for Key -> value "{}" braces while building Json

Scala - Couldn't remove double quotes for "{}" braces while building Json
import scala.util.Random
import math.Ordered.orderingToOrdered
import math.Ordering.Implicits.infixOrderingOps
import play.api.libs.json._
import play.api.libs.json.Writes
import play.api.libs.json.Json.JsValueWrapper
val data1 = (1 to 2)
.map {r => Json.toJson(Map(
"name" -> Json.toJson(s"Perftest${Random.alphanumeric.take(6).mkString}"),
"domainId"->Json.toJson("343RDFDGF4RGGFG"),
"value" ->Json.toJson("{}")))}
val data2 = Json.toJson(data1)
println(data2)
Result :
[{"name":"PerftestpXI1ID","domainId":"343RDFDGF4RGGFG","value":"{}"},{"name":"PerftestHoZSQR","domainId":"343RDFDGF4RGGFG","value":"{}"}]
Expected :
"value":{}
[{"name":"PerftestpXI1ID","domainId":"343RDFDGF4RGGFG","value":{}},{"name":"PerftestHoZSQR","domainId":"343RDFDGF4RGGFG","value":{}}]
Please suggest a solution
You are giving it a String so it is creating a string in JSON. What you actually want is an empty dictionary, which is a Map in Scala:
val data1 = (1 to 2)
.map {r => Json.toJson(Map(
"name" -> Json.toJson(s"Perftest${Random.alphanumeric.take(6).mkString}"),
"domainId"->Json.toJson("343RDFDGF4RGGFG"),
"value" ->Json.toJson(Map.empty[String, String])))}
More generally you should create a case class for the data and create a custom Writes implementation for that class so that you don't have to call Json.toJson on every value.
Here is how to do the conversion using only a single Json.toJson call:
import play.api.libs.json.Json
case class MyData(name: String, domainId: String, value: Map[String,String])
implicit val fmt = Json.format[MyData]
val data1 = (1 to 2)
.map { r => new MyData(
s"Perftest${Random.alphanumeric.take(6).mkString}",
"343RDFDGF4RGGFG",
Map.empty
)
}
val data2 = Json.toJson(data1)
println(data2)
The value field can be a standard type such as Boolean or Double. It could also be another case class to create nested JSON as long as there is a similar Json.format line for the new type.
More complex JSON can be generated by using a custom Writes (and Reads) implementation as described in the documentation.

Unable to parse a json string Binary in spark scala

I have a Binary json array string which I need to parse in Spark scala.
This is what I am doing:
import com.github.wnameless.json.flattener.JsonFlattener
def extractBlob(jsonString: String,
defaultValue: String = ""): String = {
JsonFlattener
.flatten(jsonString)
.toString
}
val extractBlobAsText = udf((jS: String) => extractBlob(jS))
val df1 =
df.withColumn("extracted",extractBlobAsText(unhex(col("hex").cast(StringType))))
df1.show(false)
But I am getting this error
com.eclipsesource.json.ParseException: Unexpected end of input at 1:1 at
com.eclipsesource.json.JsonParser.error(JsonParser.java:490) at
com.eclipsesource.json.JsonParser.expected(JsonParser.java:484) at
com.eclipsesource.json.JsonParser.readValue(JsonParser.java:193) at
com.eclipsesource.json.JsonParser.parse(JsonParser.java:152) at
com.eclipsesource.json.JsonParser.parse(JsonParser.java:91) at
com.eclipsesource.json.Json.parse(Json.java:295) at
com.github.wnameless.json.flattener.JsonFlattener.<init>(JsonFlattener.java:144) at
com.github.wnameless.json.flattener.JsonFlattener.flatten(JsonFlattener.java:100) at
notebook0.Cell5$285.extractBlob(Cell5:12) at
Also, I do not know the JSON schema. All I know is that it is a Json array. So I also need to do explode later.

Extract a Json from an array inside a json in spark

I have a complicated JSON column whose structure is :
story{
cards: [{story-elements: [{...}{...}{...}}]}
The length of the story-elements is variable. I need to extract a particular JSON block from the story-elements array. For this, I first need to extract the story-elements.
Here is the code which I have tried, but it is giving error:
import org.json4s.{DefaultFormats, MappingException}
import org.json4s.jackson.JsonMethods._
import org.apache.spark.sql.functions._
def getJsonContent(jsonstring: String): (String) = {
implicit val formats = DefaultFormats
val parsedJson = parse(jsonstring)
val value1 = (parsedJson\"cards"\"story-elements").extract[String]
value1
}
val getJsonContentUDF = udf((jsonstring: String) =>
getJsonContent(jsonstring))
input.withColumn("cards",getJsonContentUDF(input("storyDataFrame")))
According to json you provided, story-elements is a an array of json objects, but you trying to extract array as a string ((parsedJson\"cards"\"story-elements").extract[String]).
You can create case class representing on story (like case class Story(description: String, pageUrl: String, ...)) and then instead of extract[String], try extract[List[Story]] or extract[Array[Story]]
If you need just one piece of data from story (e.g. descrition), then you can use xpath-like syntax to get that and then extract List[String]

Convert scala json string to an object

I need to convert a string json in an object using scala.
I tried this, but I cannot access the prop Name, for example
import scala.util.parsing.json._
val parsed = JSON.parseFull("""{"Name":"abc", "age":10}""")
How can I do to get an string json and convert to an object? Thanks
val parsed = JSON.parseFull("""{"Name":"abc", "age":10}""")
val parsed = JSON.parseFull(parsed)
try it

Create MongodbObject using bson.util

I have a JsValue(spray.json.JsValue) which is in JSON format. I need to convert this JSON value to a MongodbObject using bson.util. How can I do this ?
You've probably got an answer for this already, but since i was just looking for a way to do the same conversion I thought I'd leave an answer. This worked for me.
You can convert it to a String using spray.json and use the JSON.parse provided by com.mongodb.util.JSON.
The trick is to remove the additional double quotes at the start and end of the string so that JSON.parse recognises it as a json object instead of a JSON String.
import spray.json._
import DefaultJsonProtocol._
val json = "{'foo':'baa'}"
val jsValue = json.toJson
val slicedJson = jsValue.toString().slice(1, jsValue.toString().length - 1)
val dbObject = JSON.parse(slicedJson).asInstanceOf[DBObject]