开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜