Odd behavior with using transform function to postprocess AST in order to rename json field name
Chances are that I am doing this wrong, but here goes. I'm using lift-json to turn a json response string into an object. The response string I get has some names for fields that aren't the best idea to use in Scala, i.e. option. I wanted to write a "helper" function that is pretty much just a wrapper around JValue.transform:
def renameFields(originalJson : JValue, oldFieldName : String, newFieldName : String): JValue = {
originalJson transform { case JField(oldFieldName,x) => JField(newFieldName, x)}
}
Here is the sample response string and JObject I'm working with:
scala> val jstring = """ { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }"""
jstring: java.lang.String = { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }
scala> val json = parse(jstring)
json: net.liftweb.json.JsonAST.JValue = JObject(List(JField(aisle,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))
If I use this function, all the field names end up getting changed:
scala> Util.renameFields(json,"aisle","row")
res2: net.liftweb.json.JsonAST.JValue = JObject(List(JField(row,JInt(1)), JField(row,JInt(1)), JField(row,JArray(List(JObject(List(JField(row,JInt(4)), JField(row,JString(Granny)), JField(row,JString(green)))), JObject(List(JField(row,JInt(4)), JField(row,JString(Fuji)), JField(row,JString(red)))))))))
And what I actually want is:
scala> json transform { case JField("aisle",x) => JField("row",x) }
res3: net.liftweb.json.JsonAST.JValue = JObject(List(JField(row,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))
开发者_JAVA百科
So...what am I doing wrong? Thanks in advance.
-Still Newbie
I think all you're missing is backticks around oldFieldName
:
scala> def renameFields(originalJson : JValue, oldFieldName : String, newFieldName : String): JValue = originalJson transform { case JField(`oldFieldName`,x) => JField(newFieldName, x)}
renameFields: (originalJson: net.liftweb.json.JsonAST.JValue,oldFieldName: String,newFieldName: String)net.liftweb.json.JsonAST.JValue
scala> val jstring = """ { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }"""
jstring: java.lang.String = { "aisle" : 1, "bin" : 1, "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, { "id" : 4, "name" : "Fuji", "color" : "red"}] }
scala> val json = parse(jstring)
json: net.liftweb.json.JsonAST.JValue = JObject(List(JField(aisle,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))
scala> renameFields(json,"aisle","row")
res0: net.liftweb.json.JsonAST.JValue = JObject(List(JField(row,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))
Without the backticks, case JField(oldFieldName,x)
is saying "bind whatever value I find as the JField
name to the new variable oldFieldName
" and thus your original oldFieldName
variable is shadowed. With the backticks around oldFieldName
, you're saying you only want to match a JField
whose name is the value of oldFieldName
.
精彩评论