使用转换函数对 AST 进行后处理以重命名 json 字段名称时出现奇怪的行为
我很可能做错了,但事情就是这样。我正在使用 lift-json 将 json 响应字符串转换为对象。我得到的响应字符串有一些字段名称,这些名称不是在 Scala 中使用的最佳主意,即选项。我想编写一个“帮助器”函数,它几乎只是 JValue.transform 的包装器:
def renameFields(originalJson : JValue, oldFieldName : String, newFieldName : String): JValue = {
originalJson transform { case JField(oldFieldName,x) => JField(newFieldName, x)}
}
这是我正在使用的示例响应字符串和 JObject:
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> 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)))))))))
而我真正想要的是:
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)))))))))
那么……我做错了什么?提前致谢。
-还是新手
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)))))))))
So...what am I doing wrong? Thanks in advance.
-Still Newbie
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您缺少的只是
oldFieldName
周围的反引号:如果没有反引号,
case JField(oldFieldName,x)
会说“将我找到的任何值绑定为JField
名称到新变量oldFieldName
”,因此您的原始oldFieldName
变量被隐藏。通过oldFieldName
周围的反引号,您表示您只想匹配名称为oldFieldName
值的JField
。I think all you're missing is backticks around
oldFieldName
:Without the backticks,
case JField(oldFieldName,x)
is saying "bind whatever value I find as theJField
name to the new variableoldFieldName
" and thus your originaloldFieldName
variable is shadowed. With the backticks aroundoldFieldName
, you're saying you only want to match aJField
whose name is the value ofoldFieldName
.