groovy YAML 删除几行
groovy YAML delete few lines
使用 groovy yaml 解析器我需要删除以下行并写入文件。
要删除的行。
- name: hostname
required: true
secure: false
valueExposed: true
当我尝试加载要映射的 yaml 数据时。它失败了 'org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '
异常。
我正在寻求帮助。如何加载此 yaml 数据并从中删除 4 行。
import org.yaml.snakeyaml.DumperOptions
import org.yaml.snakeyaml.Yaml
class Test {
def static main(args) {
DumperOptions options = new DumperOptions()
options.setPrettyFlow(true)
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK)
Yaml yaml = new Yaml(options)
def Map map = (Map) yaml.load(data)
println yaml.dump(map)
}
def static String data = '''
- description: checkc the disk spacce
executionEnabled: true
loglevel: INFO
name: disk spacce
options:
- description: file system name
name: filesystem
required: true
- name: hostname
required: true
secure: false
valueExposed: true
scheduleEnabled: true
sequence:
commands:
- exec: df -h
keepgoing: false
'''
}
如果您仔细查看异常消息,您会注意到您正在尝试将 List
转换为 Map
,这会引发 ClassCastException
。您肯定需要阅读和理解 YAML 结构,因为您在之前的 .
中犯了同样的错误
所以要将数据加载到列表中:
List list = (List) yaml.load(data)
现在,如果您确定 yaml 数据的结构,那么您可以使用 list.first().options.remove(1)
.
以丑陋但直接的方式删除数据
或者您可以遍历数据并找到需要删除的数据,然后将其删除。
static Map dataToBeRemoved = [
name : 'hostname',
required : true,
secure : false,
valueExposed: true
]
public static findAndRemoveMap(List list) {
Object o
ListIterator iterator = list.listIterator()
while (iterator.hasNext()) {
o = iterator.next()
if (o instanceof Map) {
if (compareJsonObjects(dataToBeRemoved, o)) {
iterator.remove()
} else {
o.findAll { it.value instanceof List }.each {
findAndRemoveMap(it.value)
}
}
} else if (o instanceof List) {
findAndRemoveMap(o)
}
}
}
compareJsonObjects
是比较两个map和return是否相等的方法。您可以创建自己的实现,也可以使用外部库,例如 skyscreamer
中的 jsonassert
。使用 jsonassert
,compareJsonObjects
的实现将是:
public static boolean compareJsonObjects(Map<String, Object> obj_1, Map<String, Object> obj_2) {
String one = new groovy.json.JsonBuilder(obj_1).toPrettyString()
String two = new groovy.json.JsonBuilder(obj_2).toPrettyString()
JSONCompareResult r = JSONCompare.compareJSON(one, two, JSONCompareMode.NON_EXTENSIBLE)
return r.passed()
}
正如@sandeep-poonia 已经提到的,转换异常是因为 Map 数据类型,您可以参考此代码来解析和删除这些行。
static Map dataToBeRemoved = [
name : 'hostname',
required : true,
secure : false,
valueExposed: true
]
static def removeEntries
removeEntries = {def yaml ->
if(yaml.getClass() == ArrayList){
yaml = yaml.collect {
removeEntries(it)
}
yaml = yaml.findAll{it} // remove empty items (list or map) from list.
} else if(yaml.getClass() == LinkedHashMap){
if(!(dataToBeRemoved - yaml)){
yaml = yaml - dataToBeRemoved
}
yaml.each{
yaml[it.key] = removeEntries(it.value)
}
}
yaml
}
def static main(args){
DumperOptions options = new DumperOptions()
options.setPrettyFlow(true)
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK)
Yaml yaml = new Yaml(options)
List yamlData = yaml.load(data)
yamlData = removeEntries(yamlData)
println yaml.dump(yamlData)
}
使用 groovy yaml 解析器我需要删除以下行并写入文件。
要删除的行。
- name: hostname
required: true
secure: false
valueExposed: true
当我尝试加载要映射的 yaml 数据时。它失败了 'org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object ' 异常。
我正在寻求帮助。如何加载此 yaml 数据并从中删除 4 行。
import org.yaml.snakeyaml.DumperOptions
import org.yaml.snakeyaml.Yaml
class Test {
def static main(args) {
DumperOptions options = new DumperOptions()
options.setPrettyFlow(true)
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK)
Yaml yaml = new Yaml(options)
def Map map = (Map) yaml.load(data)
println yaml.dump(map)
}
def static String data = '''
- description: checkc the disk spacce
executionEnabled: true
loglevel: INFO
name: disk spacce
options:
- description: file system name
name: filesystem
required: true
- name: hostname
required: true
secure: false
valueExposed: true
scheduleEnabled: true
sequence:
commands:
- exec: df -h
keepgoing: false
'''
}
如果您仔细查看异常消息,您会注意到您正在尝试将 List
转换为 Map
,这会引发 ClassCastException
。您肯定需要阅读和理解 YAML 结构,因为您在之前的
所以要将数据加载到列表中:
List list = (List) yaml.load(data)
现在,如果您确定 yaml 数据的结构,那么您可以使用 list.first().options.remove(1)
.
或者您可以遍历数据并找到需要删除的数据,然后将其删除。
static Map dataToBeRemoved = [
name : 'hostname',
required : true,
secure : false,
valueExposed: true
]
public static findAndRemoveMap(List list) {
Object o
ListIterator iterator = list.listIterator()
while (iterator.hasNext()) {
o = iterator.next()
if (o instanceof Map) {
if (compareJsonObjects(dataToBeRemoved, o)) {
iterator.remove()
} else {
o.findAll { it.value instanceof List }.each {
findAndRemoveMap(it.value)
}
}
} else if (o instanceof List) {
findAndRemoveMap(o)
}
}
}
compareJsonObjects
是比较两个map和return是否相等的方法。您可以创建自己的实现,也可以使用外部库,例如 skyscreamer
中的 jsonassert
。使用 jsonassert
,compareJsonObjects
的实现将是:
public static boolean compareJsonObjects(Map<String, Object> obj_1, Map<String, Object> obj_2) {
String one = new groovy.json.JsonBuilder(obj_1).toPrettyString()
String two = new groovy.json.JsonBuilder(obj_2).toPrettyString()
JSONCompareResult r = JSONCompare.compareJSON(one, two, JSONCompareMode.NON_EXTENSIBLE)
return r.passed()
}
正如@sandeep-poonia 已经提到的,转换异常是因为 Map 数据类型,您可以参考此代码来解析和删除这些行。
static Map dataToBeRemoved = [
name : 'hostname',
required : true,
secure : false,
valueExposed: true
]
static def removeEntries
removeEntries = {def yaml ->
if(yaml.getClass() == ArrayList){
yaml = yaml.collect {
removeEntries(it)
}
yaml = yaml.findAll{it} // remove empty items (list or map) from list.
} else if(yaml.getClass() == LinkedHashMap){
if(!(dataToBeRemoved - yaml)){
yaml = yaml - dataToBeRemoved
}
yaml.each{
yaml[it.key] = removeEntries(it.value)
}
}
yaml
}
def static main(args){
DumperOptions options = new DumperOptions()
options.setPrettyFlow(true)
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK)
Yaml yaml = new Yaml(options)
List yamlData = yaml.load(data)
yamlData = removeEntries(yamlData)
println yaml.dump(yamlData)
}