2010-11-03 35 views
3

Il y a des chances que je fasse cela mal, mais c'est parti. J'utilise lift-json pour transformer une chaîne de réponse json en un objet. La chaîne de réponse que je reçois a des noms pour les champs qui ne sont pas la meilleure idée à utiliser dans Scala, c'est-à-dire l'option. Je voulais écrire une fonction « aide » qui est à peu près juste un wrapper autour JValue.transform:Comportement impair avec l'utilisation de la fonction de transformation pour post-traiter AST afin de renommer le nom de champ json

def renameFields(originalJson : JValue, oldFieldName : String, newFieldName : String): JValue = { 
    originalJson transform { case JField(oldFieldName,x) => JField(newFieldName, x)} 
} 

Voici la chaîne de réponse de l'échantillon et jobject Je travaille avec:

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))))))))) 

Si J'utilise cette fonction, tous les noms de champs finissent par se changer:

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))))))))) 

Et ce que je veux réellement est:

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))))))))) 

Alors ... qu'est-ce que je fais mal? Merci d'avance.

-Toujours Débutant

Répondre

4

Je pense que tout ce que vous êtes absent est autour oldFieldName: accents graves

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))))))))) 

Sans les accents graves, case JField(oldFieldName,x) est dire « lier quelle que soit la valeur que je trouve que le nom JField à la nouvelle variable oldFieldName "et donc votre variable originale oldFieldName est ombrée. Avec les balises en arrière autour de oldFieldName, vous dites que vous voulez seulement correspondre à un JField dont le nom est la valeur de oldFieldName.

+0

(* insérer la paroi ci-contre *) D'oh. La malédiction des backticks/frontticks/citations manquants. Merci Steve, je n'aurais jamais pensé utiliser n'importe quel type de tick ou de citation dans la méthode. Par curiosité, comment as-tu su faire ça? – CaffiendFrog

+1

Je pense que c'est probablement en lisant le http://stackoverflow.com/questions/1332574/common-programming-mistakes-for-scala-developers-to-avoid thread, en particulier le "Utilisation d'identifiants commençant par une lettre minuscule dans le motif "correspondance" mentionne les backticks. – Steve

+0

Merci encore Steve! C'est un message très utile. – CaffiendFrog