【问题标题】:How to get key from ArrayList nested in JSON using Groovy and change its value如何使用 Groovy 从嵌套在 JSON 中的 ArrayList 获取键并更改其值
【发布时间】:2018-03-15 02:02:28
【问题描述】:

我需要能够找到键 quote.orderAttributes[0].attributeDetail.name 并将其值设置为 null 或我想要的任何其他值。我只需要对任何列表中的第一个元素执行此操作,因此选择 [0] 就可以了。我希望能够使用诸如“quote.orderAttributes.attributeDetail.name”之类的路径。但鉴于我到目前为止所花费的时间,请告知任何更好的方法。

这是 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"
      }
    ]
  }
}

我知道以下工作,但要求我知道哪个对象是 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

我希望能够:

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

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

如果您能指出一篇解释序列化和反序列化的好文章,我将不胜感激。

提前谢谢你。

【问题讨论】:

  • 你不能避免明确的attributes[0],因为简单地说attributes也是一个有效的引用,但是指向一个完整的对象列表。当您明确说出 attributes[0] 时,您指向的是该列表的特定元素。

标签: json arraylist groovy jsonbuilder jsonslurper


【解决方案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')

【讨论】:

  • 完美!!我希望很多人来这篇文章并投票给你的答案。该站点上还有许多其他问题与此问题类似,但解决方案要复杂得多。评估对我来说是新的。很好的答案!!!
【解决方案2】:

您可以直接访问和修改 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

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 2022-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    相关资源
    最近更新 更多