如何使用Groovy从嵌套在JSON中的ArrayList获取密钥并更改其值

时间:2017-10-03 19:26:02

标签: json arraylist groovy jsonbuilder jsonslurper

我需要能够找到密钥CREATE FUNCTION [dbo].[tvf-Date-Elapsed] (@D1 DateTime,@D2 DateTime) Returns Table Return ( with cteBN(N) as (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)), cteRN(R) as (Select Row_Number() Over (Order By (Select NULL))-1 From cteBN a,cteBN b,cteBN c), cteYY(N,D) as (Select Max(R),Max(DateAdd(YY,R,@D1))From cteRN R Where DateAdd(YY,R,@D1)<=@D2), cteMM(N,D) as (Select Max(R),Max(DateAdd(MM,R,D)) From (Select Top 12 R From cteRN Order By 1) R, cteYY P Where DateAdd(MM,R,D)<=@D2), cteDD(N,D) as (Select Max(R),Max(DateAdd(DD,R,D)) From (Select Top 31 R From cteRN Order By 1) R, cteMM P Where DateAdd(DD,R,D)<=@D2), cteHH(N,D) as (Select Max(R),Max(DateAdd(HH,R,D)) From (Select Top 24 R From cteRN Order By 1) R, cteDD P Where DateAdd(HH,R,D)<=@D2), cteMI(N,D) as (Select Max(R),Max(DateAdd(MI,R,D)) From (Select Top 60 R From cteRN Order By 1) R, cteHH P Where DateAdd(MI,R,D)<=@D2), cteSS(N,D) as (Select Max(R),Max(DateAdd(SS,R,D)) From (Select Top 60 R From cteRN Order By 1) R, cteMI P Where DateAdd(SS,R,D)<=@D2) Select [Years] = cteYY.N ,[Months] = cteMM.N ,[Days] = cteDD.N ,[Hours] = cteHH.N ,[Minutes] = cteMI.N ,[Seconds] = cteSS.N --,[Elapsed] = Format(cteYY.N,'0000')+':'+Format(cteMM.N,'00')+':'+Format(cteDD.N,'00')+' '+Format(cteHH.N,'00')+':'+Format(cteMI.N,'00')+':'+Format(cteSS.N,'00') From cteYY,cteMM,cteDD,cteHH,cteMI,cteSS ) --Max 1000 years --Select * from [dbo].[tvf-Date-Elapsed] ('1991-09-12 21:00:00.000',GetDate()) --Select * from [dbo].[tvf-Date-Elapsed] ('2017-01-01 20:30:15','2018-02-05 22:58:35') 并将其值设置为quote.orderAttributes[0].attributeDetail.name或我想要的任何其他值。我只需要为任何列表中的第一个元素执行此操作,因此选择[0]就可以了。我希望能够使用诸如'quote.orderAttributes.attributeDetail.name'之类的路径。但考虑到我到目前为止所花费的时间,请告知任何更好的方法。

这是Json:

null

我知道以下工作,但要求我知道哪个对象是{ "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" } ] } } 并指定其ArrayList索引项:

[0]

我希望能够:

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

我试图在这里使用递归实现许多示例,创建MapsOrCollections的方法识别对象是什么,然后搜索它的键或值,甚至是蹦床的例子。

如果您能指出我一篇解释序列化和反序列化的好文章,我们也会非常感激。

提前谢谢。

2 个答案:

答案 0 :(得分:1)

作为变体:

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

答案 1 :(得分:0)

您可以直接访问和修改JSON对象的任何嵌套字段,例如

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

这是可能的,因为new JsonSlurper().parse(input)会返回groovy.json.internal.LazyMap个对象。 Groovy允许您使用点表示法访问和修改任何Map条目,例如

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'

您可以对您的示例应用相同的方法,例如

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

我希望它有所帮助。