Search code examples
javayamlsnakeyaml

SnakeYAML Dump nested key


I am using SnakeYAML as my YAML parser for a project, and I don't know how to set keys that are nested. For instance, here is a YAML file with nested keys in it.

control:
  advertising:
    enabled: true
logging:
  chat: true
  commands: true
  format: '%id% %date% %username% | %value%'

My goal is to be able to easily set the path control.advertising.enabled or any other path to any value.

When I use

void Set(String key, Object value, String configName){
    Yaml yaml = new Yaml();
    OutputStream oS;
    try {
        oS = new FileOutputStream(main.getDataFolder() + File.separator + configName);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return;
    }
    Map<String, Object> data = new HashMap<String, Object>();
    // set data based on original + modified
    data.put(key, value);
    String output = yaml.dump(data);

    try {
        oS.write(output.getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

to set the value, instead of getting

logging:
  chat: true
  commands: true
  format: '%id% %date% %username% | %value%'

the entire yaml file is cleared and I only get {logging.chat: false}

Thank you!


Solution

  • Define your structure with Java classes:

    public class Config {
        public static class Advertising {
            public boolean enabled;
        }
        public static class Control {
            public Advertising advertising;
        }
        public static class Logging {
            public boolean chat;
            public boolean commands;
            public String format;
        }
    
        Control control;
        Logging logging;
    }
    

    Then you can modify it like this:

    Yaml yaml = new Yaml();
    Config config = yaml.loadAs(inputStream, Config.class);
    config.control.advertising.enabled = false;
    String output = yaml.dump(config);
    

    Note that loading & saving YAML data this way might mess with the order of mapping keys, because this order is not preserved. I assume that the output order will be according to the field order in the Java classes, but I'm not sure.