Разбор вложенных JSON в groovy - PullRequest
0 голосов
/ 17 марта 2020

Я хотел бы проанализировать вложенные ниже JSON в Groovy и получить значения "it", "ft", "stg", "prd" для каждого приложения и сохранить их в отдельном массиве. Может кто-нибудь помочь пожалуйста?

    {
        "Application1": {
            "environments": {
                "it": [
                    "server1"
                ],
                "ft": [
                    "server2"
                ],
                "stg": [
                    "server3"
                ],
                "prd": [
                    "server4"
                ]
            },
            "war-path" : "/opt/tomcat/",
            "war-name" : "Application1"
        },
        "Application2": {
            "environments": {
                "it": [
                    "serverA"
                ],
                "ft": [
                    "serverB"
                ],
                "stg": [
                    "serverC"
                ],
                "prd": [
                    "serverD"
                ]
            },
            "war-path" : "/var/lib",
            "war-name" : "Application2"
        }
    }
}

Ожидаемый результат будет примерно таким, как показано ниже в отдельном списке для каждой среды. Также 1-й уровень (Приложение1, Приложение2 ..) будет динамическим c всегда

it = [server1,serverA]
ft = [server2,serverB]
stg = [server3, serverC]
prd = [server4,serverD]

Обновлено: После получения ожидаемого ответа с входными данными от Филиппа Wrage.

def projects = readJSON file: "${env.WORKSPACE}//${infrafile}"
def json_str = JsonOutput.toJson(projects)
def json_beauty = JsonOutput.prettyPrint(json_str)
def envlist = ["it","ft","stg","prd"]
def fileListResult = []


for (envname in envlist) {
    servers=serverlist(json_beauty,envname)
    println(servers)
}

def serverlist(json_beauty,envname){
    def jsonSlurper = new JsonSlurper()
    def jsonMap = jsonSlurper.parseText(json_beauty)

    assert jsonMap instanceof Map
    jsonMap.each { appName, appDetails ->

        assert appDetails instanceof Map
        appDetails.environments.each { envName, servers ->
            for (items in servers{
                if (envName == "${envname}"){
                    fileListResult.add(items)
                }
            }
        }        
    }
    return fileListResult
}

Ответы [ 2 ]

2 голосов
/ 18 марта 2020

Как рекомендует @Chris, вы можете использовать встроенный JsonSlurper для анализа JSON, а затем перемещаться по проанализированным результатам как Map.

В В следующем примере я покажу, как можно просто распечатать результаты на консоли. Однако, используя это в качестве руководства, вы можете увидеть, как извлекать данные в любую структуру данных, соответствующую вашим целям.

Предположим, что у вас есть JSON в переменной String jsonText , Возможно, вы извлекаете данные из файла или HTTP POST, или из того, что требует ваше приложение. Я использовал следующий код, чтобы установить это значение для тестирования.

def jsonText = """
{
    "Application1": {
    "environments": {
        "it": [
                "server1"
        ],
        "ft": [
                "server2"
        ],
        "stg": [
                "server3"
        ],
        "prd": [
                "server4"
        ]
    },
    "war-path" : "/opt/tomcat/",
    "war-name" : "Application1"
},
    "Application2": {
    "environments": {
        "it": [
                "serverA"
        ],
        "ft": [
                "serverB"
        ],
        "stg": [
                "serverC"
        ],
        "prd": [
                "serverD"
        ]
    },
    "war-path" : "/var/lib",
    "war-name" : "Application2"
}
}
"""

Далее следует описание решения. Разберите текст JSON в Map, а затем переберите записи в этом Map, выполнив все необходимые операции. Серверы для каждой среды уже будут содержаться в List.

import groovy.json.JsonSlurper

def jsonSlurper = new JsonSlurper()
def jsonMap = jsonSlurper.parseText(jsonText)

assert jsonMap instanceof Map

jsonMap.each { appName, appDetails ->
    println "Application: $appName"
    assert appDetails instanceof Map
    appDetails.environments.each { envName, servers ->
        assert servers instanceof List
        println "\tEnvironment: $envName"
        println "\t\t$servers"
    }
}

. Из этого кода я получаю следующий вывод консоли.

Application: Application1
    Environment: it
        [server1]
    Environment: ft
        [server2]
    Environment: stg
        [server3]
    Environment: prd
        [server4]
Application: Application2
    Environment: it
        [serverA]
    Environment: ft
        [serverB]
    Environment: stg
        [serverC]
    Environment: prd
        [serverD]

РЕДАКТИРОВАТЬ (на основе уточнения требуемого вывода):

import groovy.json.JsonSlurper

def jsonText = "\n{\n    \"Application1\": {\n    \"environments\": {\n        \"it\": [\n                \"server1\"\n        ],\n        \"ft\": [\n                \"server2\"\n        ],\n        \"stg\": [\n                \"server3\"\n        ],\n        \"prd\": [\n                \"server4\"\n        ]\n    },\n    \"war-path\" : \"/opt/tomcat/\",\n    \"war-name\" : \"Application1\"\n},\n    \"Application2\": {\n    \"environments\": {\n        \"it\": [\n                \"serverA\"\n        ],\n        \"ft\": [\n                \"serverB\"\n        ],\n        \"stg\": [\n                \"serverC\"\n        ],\n        \"prd\": [\n                \"serverD\"\n        ]\n    },\n    \"war-path\" : \"/var/lib\",\n    \"war-name\" : \"Application2\"\n}\n}\n"

def jsonSlurper = new JsonSlurper()
def jsonMap = jsonSlurper.parseText(jsonText)

def result = [:]

jsonMap.each { appName, appDetails ->
    appDetails.environments.each { envName, servers ->
        if ( !result.containsKey(envName) ) {
            result.put(envName, [])
        }
        result.get(envName).addAll(servers)
    }
}
println result

Результаты представляют собой Map, где ключами являются различные среды, указанные в файле JSON, а значения List s серверов, связанных с этими средами во всех приложениях. Вы можете получить доступ к любому List индивидуально с помощью чего-то вроде result.stg или назначить им разные переменные позже, если это желательно / необходимо (def stg = result.stg).

[it:[server1, serverA], ft:[server2, serverB], stg:[server3, serverC], prd:[server4, serverD]]
0 голосов
/ 18 марта 2020

Если вы хотите все environments, вы можете использовать оператор распространения, чтобы взять все среды из значений. Далее вам нужно слить карты по клавишам. Например,

def json = """ { "Application1": { "environments": { "it": [ "server1" ], "ft": [ "server2" ], "stg": [ "server3" ], "prd": [ "server4" ] }, }, "Application2": { "environments": { "it": [ "serverA" ], "ft": [ "serverB" ], "stg": [ "serverC" ], "prd": [ "serverD" ] }, } } }"""

def data = new groovy.json.JsonSlurper().parseText(json)

println data.values()*.environments.inject{ a, b -> 
    b.inject(a.withDefault{[]}) { m, kv -> 
        // with groovy 2.5+: m.tap{ get(kv.key).addAll(kv.value) }
        m[kv.key].addAll(kv.value); m
    } 
}
// → [it:[server1, serverA], ft:[server2, serverB], stg:[server3, serverC], prd:[server4, serverD]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...