使用 JsonSlurper 读取数组名称

Read Array name using JsonSlurper

我是 groovy 语言的新手

我正在尝试在 groovy 脚本中使用 JsonSlurper 解析 JSON 文件。如何访问下面 JSON 文件中的数组名称?即 Array1 和 Array2?而且到目前为止,我只尝试使用 findall 声明一个列表,但是如何在没有条件的情况下声明列表?

def input = new JsonSlurper().parse(reader)
def items = input.Order.Items.findAll { item -> item.Valid == "true"}

输入:

{
  "Order": {
    "Header": {
      "OrderNumber": "ORD60001",
      "Date": "20190218"
    },
    "Array1": [
      {
        "ItemNumber": "10",
        "MaterialNumber": "MT70001",
        "Quantity": 57,
        "Valid": true
      },
      {
        "ItemNumber": "20",
        "MaterialNumber": "MT80001",
        "Quantity": 28,
        "Valid": false
      }
    ],
    "Array2": [
      {
        "ItemNumber": "10",
        "MaterialNumber": "MT70001",
        "Quantity": 57,
        "Valid": true
      },
      {
        "ItemNumber": "20",
        "MaterialNumber": "MT80001",
        "Quantity": 28,
        "Valid": false
      }
    ]
  }
}

预期输出:

{
    "Order": {
        "Header": {
            "OrderNumber": "ORD60001",
            "Date": "20190218"
        },
        "Array1": [
            {
                "ItemNumber": "10",
                "MaterialNumber": "MT70001",
                "Quantity": 57,
                "Valid": true
            }
        ],
        "Array2": [
            {
                "ItemNumber": "10",
                "MaterialNumber": "MT70001",
                "Quantity": 57,
                "Valid": true
            }
        ]
    }
}

假设您想要包含“Valid: true”元素的 Order 对象的任何 属性 的名称,您可以这样做:

def entriesContainingOneValidChild = input.Order.entrySet()
    .findAll { item -> item.value.Valid?.any() }.key

啊我现在明白了...

您可能想要更多这样的东西:

def filtered = [
    Order: new JsonSlurper().parse(reader)
               .Order
               .entrySet()
               .collectEntries {
                   it.value instanceof List ?
                       [it.key, it.value.findAll { it.Valid }] :
                       it
               }
]
​println new JsonBuilder(filtered).toPrettyString()

为新结构编辑:

def validArrayEntries = input.Order.entrySet().findResults { entry ->
    // Go through all the orders, and find the ones that are lists
    if (entry.value instanceof List) {

        // Count the number of ones that are Valid
        def validEntries = entry.value.count { it.Valid }

        // If there are valid entries, then keep only them
        if (validEntries > 0) {
            [(entry.key): entry.value.findAll { it.Valid }]
        }
    }
}.collectEntries() // This collects them back into a map

// Then we can define our required JSON model               
def model = [
    PurchaseOrder: [
        HeaderData: [ ID:  input.Order.Header.OrderNumber ],

        // And this injects the map from above into this map
        *:validArrayEntries
    ]
]

def builder = new JsonBuilder(model).toPrettyString()

我已经对代码进行了注释,并尽量使其易于理解,如果需要更多解释,请告诉我