Search code examples
javaspringyamlsnakeyaml

Snake yaml : Issue with duplicate keys in Yaml template


I have a Yaml template which needs to be updated dynamically.

I am reading Yaml template using snake yaml and updating it with dynamic content and generating new yaml file with new values

I am following below steps to update yaml file.

  1. Assume below is the Yaml template
--------------------------------
version: snapshot-01
kind: sample
metadata:
  name: abc
options: "<placeholder>"
--------------------------------

I am converting yaml into Map using snake yaml as shown below

 Yaml yaml = new Yaml();
 InputStream inputStream = 
 this.getClass().getClassLoader().getResourceAsStream(yamlTemplateLocation);
 Map<String, Object>yamlMap = yaml.load(inputStream); 

I am replacing the required fields dynamically as shown below.

yamlMap.put("version","v-1.0");
yamlMap.put("options","newOptions");

And finally I am converting map to String and strore as Yaml file using below code :

DumperOptions options = new DumperOptions();
options.setSplitLines(false);
Yaml yaml = new Yaml(options);
System.out.println(yaml.dump(yamlMap));

Generated yaml file is :

version: "v-1.0"
kind: sample
metadata:
  name: abc
options:  "newOptions"
--------------------------------

I got some issue now

The template needs to be changed as below

--------------------------------
version: snapshot-01
kind: sample
metadata:
  name: abc
options: "<placeholder>"
---
version: v2
kind: sample
metadata:
 type: <abc> 
--------------------------------

I have to include some extra piece in the template which includes three dashes and also same same keys like version, kind and metadata

Now I need to update template with new values as shown below

version: "v-1.0"
kind: sample
metadata:
  name: abc
options:  "newOptions"
---
version: v2-0
kind: sample
metadata:
 type: "newType"

My question is --> I am converting yaml to map to update. So how can I handle if there are duplicate keys in yaml (like version, version) in the above example.

Could anyone please help me with this? Thanks in advance!


Solution

  • Three dashes mark the end of the YAML document and the begin of a new document in this case, meaning you have multiple YAML documents in a single file. In that case, you need to use loadAll to load all documents, and then dumpAll to write a file with multiple documents:

    List<Object> output = new ArrayList<Object>();
    boolean first = true;
    for (Map<String, Object> doc : yaml.loadAll(inputStream)) {
      if (first) {
        doc.put("version","v-1.0");
        doc.put("options","newOptions");
        first = false;
      }
      output.add(doc);
    }
    System.out.println(yaml.dumpAll(output));
    

    You won't have problems with duplicate keys because they are in different documents.