【问题标题】:How to pass String as a Property in Groovy. Multi-level JSON如何在 Groovy 中将字符串作为属性传递。多级 JSON
【发布时间】:2020-05-12 23:47:48
【问题描述】:

我真的很难在我正在处理的将字符串传递到多级 JSON 的代码中找出一些东西。我知道 groovy 会将 example ="multi.level "$example" 视为一个属性,我一直在尝试弄清楚如何拆分字符串保留分隔符,然后将其添加到 if 语句中,但没有任何成功。我有查看了其他解决方案,但无法让它们在我的情况下工作......任何帮助将不胜感激。

JSON:

scriptOutput: [
  {
    "id": 1,
    "data": {
      "name": "fyre-discard-vm-1007"
    },
    "key": "ABCDE123"
  },
  {
    "id": 2,
    "data": {
      "name": "fyre-discard-vm-1008"
    },
    "key": "ABCYRE123"
  },
  {
    "id": 3,
    "data": {
      "name": "fyre-discard-vm-1009"
    },
    "key": "AZREDE123"
  },
  {
    "id": 4,
    "data": {
      "name": "fyre-discard-vm-1010"
    },
    "key": "YTNER857"
  },
  {
    "id": 5,
    "data": {
      "name": "fyre-discard-vm-1011"
    },
    "key": "YANT76563A"
  },
  {
    "id": 6,
    "data": {
      "name": "fyre-discard-vm-1012"
    },
    "key": "DYAN31685"
  },
  {
    "id": 7,
    "data": {
      "name": "fyre-discard-vm-1013"
    },
    "key": "SANF84923"
  },
  {
    "id": 8,
    "data": {
      "name": "fyre-discard-vm-1014"
    },
    "key": "SADNS57985"
  },
  {
    "id": 9,
    "data": {
      "name": "fyre-discard-vm-1015"
    },
    "key": "DYUIK89OP"
  },
  {
    "id": 10,
    "data": {
      "name": "fyre-discard-vm-1016"
    },
    "key": "DHJMNNB6547"
  }
]

代码

#!/usr/local/bin/groovy
import groovy.json.*


def proc7 = "curl  https://my-json-server.typicode.com/owainow/privateAPI/machines".execute().text

def slaveList = ["fyre-discard-vm-1007","fyre-discard-vm-1015","fyre-discard-vm-1016"]
def deleteMap=[:]
def jsonName = "data.name"

    println "scriptOutput: ${proc7}"
 def json = new groovy.json.JsonSlurper().parseText(proc7)
  for (slave in slaveList)
{
  println(slave);
  if (json.find{it.data.name==slave}){ //This works as the properties are passed through as properties
  id = json.find{it.data.name==slave}.key
    deleteMap = deleteMap+[(slave):(id)]

// I would like to do something like this however I cannot figure out how to split my properties and pass them through in a way that works
/* if (json.find{it."$jsonName"==slave}){           SOMEHOW expand or split jsonName here
  id = json.find{it."$jsonName"==slave}.key
    deleteMap = deleteMap+[(slave):(id)] */

    println "Match"
    println (id)
    println deleteMap;
  }
  else{
    println"No"

  }

}

大家好。

【问题讨论】:

  • 你想达到什么目的? jsonName 变量中有什么?
  • @daggett 我需要停止在深夜发布问题。我添加了 jsonName,我希望它在这种情况下包含“data.name”,尽管它会有些动态。根据运行情况,可能是一层深度,也可能是四层。

标签: java json parsing groovy properties


【解决方案1】:

你为什么需要这个?为什么 jsonName 应该是一个字符串?

问这个是因为从json 得到deleteMap 是非常简单的常规表达:

def deleteMap= json.findAll{ it.data.name in slaveList }.collectEntries{ [it.id, it.data.name]  }

但是,如果您仍然需要它 - groovy 支持动态表达式评估:

def jsonName = "ROOT.data.name"
def deleteMap= json.findAll{ Eval.me('ROOT', it, jsonName) in slaveList }.collectEntries{ [it.id, Eval.me('ROOT', it, jsonName)]  }

【讨论】:

  • 它是一个字符串的原因是因为 jsonName 是动态的。 jsonName 可以是“data.name”,也可以是“hello.its.me”,这取决于用户的 json 数据。用户决定 jsonName 是什么。
  • 所以,我给了你一个提示 - Eval.me
  • 是的,谢谢,我正在使用 eval 方法,看看我目前是否能找到解决方案。
  • ROOT 在这种情况下做了什么。我看到你上面给出的代码确实有效,理论上我可以附加 ROOT。到脚本中的字符串但是我不明白它在字符串或 ('ROOT',it,jsonName) 中的用途
  • ROOT 它是变量 it 在评估表达式中的名称
【解决方案2】:

我打算建议使用 getAt() 运算符

it[jsonName]

但事实证明,您的代码中显然存在错误:

id = json.find{it."${jsonName}"==slave}.key

应该是

id = json.find{it.data."${jsonName}"==slave}.key

我仍然可能会使用

id = json.find{it.data[jsonName]==slave}.key

这是完整的、更正后的 sn-p:

import groovy.json.*


def proc7 = "curl  https://my-json-server.typicode.com/owainow/privateAPI/machines".execute().text

def slaveList = ["fyre-discard-vm-1007","fyre-discard-vm-1015","fyre-discard-vm-1016"]
def deleteMap=[:]

println "scriptOutput: ${proc7}"
def json = new groovy.json.JsonSlurper().parseText(proc7)
for (slave in slaveList)
{
    println(slave);
    if (json.find{it.data.name==slave}){ //This works as the properties are passed through as properties
        id = json.find{it.data.name==slave}.key
        deleteMap = deleteMap+[(slave):(id)]

// I would like to do something like this however I cannot figure out how to split my properties and pass them through in a way that works
/* if (json.find{it."$jsonName"==slave}){           SOMEHOW expand or split jsonName here
  id = json.find{it."$jsonName"==slave}.key
    deleteMap = deleteMap+[(slave):(id)] */

        def jsonName="name"

        id = json.find{it.data."${jsonName}"==slave}?.key
        if (id) {
            deleteMap = deleteMap+[(slave):(id)]

            println "Match"
            println (id)
            println deleteMap;
        }
    }
    else{
        println"No"

    }

}

【讨论】:

  • 感谢您的帮助,但我没有提到 jsonName 应该 = "data.name",因为我知道因此没有数据。"$jsonName"。我现在已经添加了。 “$” 方法可以传递一级属性,但是如果添加 2,该方法会将句号视为单个属性的一部分。这里的问题是将该字符串拆分或作为多级属性传递。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-03
  • 2023-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-22
  • 2018-08-16
相关资源
最近更新 更多