Groovy YAML удалить несколько строк

Используя парсер 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
'''
}

person sfgroups    schedule 10.01.2016    source источник


Ответы (2)


Если бы вы внимательно изучили сообщение об исключении, то заметили бы, что пытаетесь преобразовать 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 — это метод, который сравнивает две карты и возвращает, равны они или нет. Вы можете создать свою собственную реализацию или использовать внешнюю библиотеку, например jsonassert из skyscreamer. Используя 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()
}
person Sandeep Poonia    schedule 10.01.2016

как уже упоминалось @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)
    }
person Sachin    schedule 11.01.2016