2017-10-03 2 views
1

Je dois être en mesure de trouver la clé quote.orderAttributes[0].attributeDetail.name et définir sa valeur à null ou toute autre valeur que je veux. Je n'ai besoin de faire cela que pour le premier élément d'une liste, donc sélectionner [0] est correct. Je veux être capable d'utiliser un chemin tel que 'quote.orderAttributes.attributeDetail.name'. Mais étant donné le temps que j'ai passé jusqu'à présent, s'il vous plaît aviser de meilleures approches.Comment obtenir la clé de ArrayList imbriqué dans JSON en utilisant Groovy et modifier sa valeur

Voici le JSON:

{ 
    "source": "source", 
    "orderId": null, 
    "Version": null, 
    "quote": { 
    "globalTransactionId": "k2o4-6969-1fie-poef", 
    "quoteStatus": "Not Uploaded", 
    "events": { 
     "eventDescription": "event description", 
     "eventTypeName": "Event Type" 
    }, 
    "someReport": { 
     "acceptResultsFlag": "Y", 
     "orderDate": "2017-06-14", 
     "orderStatus": "string" 
    }, 
    "anotherReport": { 
     "id": 627311, 
     "orderDate": "2017-06-14" 
    }, 
    "attributes": [ 
     { 
     "appliedFlag": "Y", 
     "attributeDetail": { 
      "name": "name1", 
      "value": "value1" 
     }, 
     "attributeName": "attribute1" 
     }, 
     { 
     "appliedFlag": "N", 
     "attributeDetail": { 
      "name": "name2", 
      "value": "value2" 
     }, 
     "attributeName": "attribute2" 
     } 
    ], 
    "orderAttributes": [ 
     { 
     "appliedFlag": "Y", 
     "attributeDetail": { 
      "name": "name3", 
      "value": "value3" 
     }, 
     "attributeName": "orderAttribute1" 
     }, 
     { 
     "appliedFlag": "N", 
     "attributeDetail": { 
      "name": "name4", 
      "value": "value4" 
     }, 
     "attributeName": "orderAttribute2" 
     } 
    ] 
    } 
} 

Je connais les œuvres suivantes, mais exige que je sais quel objet (s) est un ArrayList et précise son [0] élément indexé:

def input = new File("src/test/resources/ShortExample.json") 
def json = new JsonSlurper().parse(input) 
def option1 = json['quote']["attributes"][0]["attributeDetail"]["name"] 
println option1 

//or this 
//where csvData.fullPath = quote.orderAttributes.attributeDetail.name 

def (tkn1, tkn2, tkn3, tkn4) = csvData.fullPath.tokenize('.') 
def option2 = json["$tkn1"]["$tkn2"][0]["$tkn3"]["$tkn4"] 
println option2 

Je voudrais comme être en mesure de:

def input = new File("src/test/resources/ShortExample.json") 
def json = new JsonSlurper().parse(input) 
def changeValueTo = null 
def (tkn1, tkn2, tkn3, tkn4) = csvData.fullPath.tokenize('.') 
json["$tkn1"]["$tkn2"]["$tkn3"]["$tkn4"] = changeValueTo 

J'ai essayé d'implémenter plusieurs f les exemples ici utilisant la récursivité, les méthodes de création de MapsOrCollections qui identifient ce qu'est l'objet, puis le recherchent pour la clé ou la valeur, même les exemples de trampoline.

Si vous pouviez me diriger vers un bon article expliquant la sérialisation et la désérialisation, ce serait également très apprécié.

Merci d'avance.

+0

Vous ne pouvez pas éviter les 'attributs explicites [0]' car simplement dire 'attributes' est aussi une référence valide mais à une liste complète d'objets. Quand vous dites explicitement 'attributes [0]' vous pointez sur un élément spécifique de cette liste. –

Répondre

0

comme variante:

import groovy.json.*; 

def json = '''{ 
    "source": "source", 
    "orderId": null, 
    "Version": null, 
    "quote": { 
    "globalTransactionId": "k2o4-6969-1fie-poef", 
    "quoteStatus": "Not Uploaded", 
    "attributes": [ 
     { 
     "appliedFlag": "Y", 
     "attributeDetail": { 
      "name": "name1", 
      "value": "value1" 
     }, 
     "attributeName": "attribute1" 
     }, 
     { 
     "appliedFlag": "N", 
     "attributeDetail": { 
      "name": "name2", 
      "value": "value2" 
     }, 
     "attributeName": "attribute2" 
     } 
    ]} 
    }''' 

json = new JsonSlurper().parseText(json) 

def jsonx(Object json, String expr){ 
    return Eval.me('ROOT',json, expr) 
} 

println jsonx(json, 'ROOT.quote.attributes[0].attributeDetail.name') 
jsonx(json, 'ROOT.quote.attributes[0].attributeDetail.name = null') 
println jsonx(json, 'ROOT.quote.attributes[0].attributeDetail.name') 
+0

Parfait !! J'espère que beaucoup viennent à ce poste et votent pour votre réponse. Il y a tellement d'autres questions sur ce site similaires à cette question mais avec des solutions beaucoup plus compliquées. Eval est nouveau pour moi. Très bonne réponse!!! – UniCoder

0

Vous pouvez accéder et modifier tous les champs de l'objet imbriqué JSON directement, par exemple,

json.quote.attributes[0].attributeDetail.name = null 

Ceci est possible, car new JsonSlurper().parse(input) retourne un objet groovy.json.internal.LazyMap. Groovy vous permet d'accéder et de modifier toutes les entrées Map en utilisant la notation par points, par ex.

Map<String, Map<String, Integer>> map = [ 
    lorem: [ipsum: 1, dolor: 2, sit: 3] 
] 

println map.lorem.ipsum // Prints '1' 
map.lorem.ipsum = 10 
println map.lorem.ipsum // Prints '10' 

Vous pouvez appliquer la même approche à votre exemple, par ex.

import groovy.json.JsonSlurper 

String input = '''{ 
    "source": "source", 
    "orderId": null, 
    "Version": null, 
    "quote": { 
    "globalTransactionId": "k2o4-6969-1fie-poef", 
    "quoteStatus": "Not Uploaded", 
    "events": { 
     "eventDescription": "event description", 
     "eventTypeName": "Event Type" 
    }, 
    "someReport": { 
     "acceptResultsFlag": "Y", 
     "orderDate": "2017-06-14", 
     "orderStatus": "string" 
    }, 
    "anotherReport": { 
     "id": 627311, 
     "orderDate": "2017-06-14" 
    }, 
    "attributes": [ 
     { 
     "appliedFlag": "Y", 
     "attributeDetail": { 
      "name": "name1", 
      "value": "value1" 
     }, 
     "attributeName": "attribute1" 
     }, 
     { 
     "appliedFlag": "N", 
     "attributeDetail": { 
      "name": "name2", 
      "value": "value2" 
     }, 
     "attributeName": "attribute2" 
     } 
    ], 
    "orderAttributes": [ 
     { 
     "appliedFlag": "Y", 
     "attributeDetail": { 
      "name": "name3", 
      "value": "value3" 
     }, 
     "attributeName": "orderAttribute1" 
     }, 
     { 
     "appliedFlag": "N", 
     "attributeDetail": { 
      "name": "name4", 
      "value": "value4" 
     }, 
     "attributeName": "orderAttribute2" 
     } 
    ] 
    } 
}''' 

def json = new JsonSlurper().parse(input.bytes) 

assert json.quote.attributes[0].attributeDetail.name == 'name1' 

json.quote.attributes[0].attributeDetail.name = null 

assert json.quote.attributes[0].attributeDetail.name == null 

J'espère que cela aide.