groovy YAML删除几行

时间:2016-01-10 02:48:41

标签: groovy yaml snakeyaml

使用groovy yaml解析器我需要删除以下行并写入文件。

删除行。

 - name: hostname
    required: true
    secure: false
    valueExposed: true

当我尝试加载yaml数据进行映射时。它的失败是' org.codehaus.groovy.runtime.typehandling.GroovyCastException:无法转换对象' 异常。

我正在寻求帮助。如何加载此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
'''
}

2 个答案:

答案 0 :(得分:1)

如果您仔细查看了异常消息,您会注意到您正试图将List转换为Map,这会抛出ClassCastException。当你在之前的question中犯了同样的错误时,你肯定需要阅读并理解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是一种比较两个地图并返回它们是否相等的方法。您可以创建自己的实现,也可以使用jsonassert中的skyscreamer等外部库。使用jsonassertcompareJsonObjects的实现将是:

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()
}

答案 1 :(得分:0)

正如@ 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)
    }