Странное поведение при использовании функции преобразования для постобработки AST с целью переименования имени поля json - PullRequest
3 голосов
/ 03 ноября 2010

Скорее всего, я делаю это неправильно, но здесь идет. Я использую 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)))))))))

Так ... что я делаю не так? Заранее спасибо.

- еще новичок

1 Ответ

4 голосов
/ 16 ноября 2010

Я думаю, что все, что вам не хватает, это обратные пометки вокруг 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)))))))))

Без обратных пометок case JField(oldFieldName,x) говорит "привязать любое значение, которое я найду как имя JField, к новомупеременная oldFieldName "и, следовательно, ваша исходная переменная oldFieldName затенена.С обратными чертами около oldFieldName вы говорите, что хотите соответствовать только JField, имя которого равно oldFieldName.

...