javayamlsnakeyaml

Snakeyaml - How to have custom control on the flow style


I am trying to create a YAML file in java with snakeyaml, and I have trouble obtaining the format I need. Some of the children are in the correct format when using DumperOptions.FlowStyle.BLOCK, while other parts are in the correct format when using the default DumperOptions.FlowStyle.AUTO. Here is a minimal example of what I mean:

Map<String,Integer> children1 = new LinkedHashMap();
children1.put("Criteria-1", 2);
children1.put("Criteria-2",1);

List<List<Object>> children2 = new ArrayList<>();
List<Object> list = new ArrayList<>();
list.add("Criteria-1");
list.add("Criteria-2");
list.add(new Integer(1));
children2.add(list);

Map<String,Object> map = new LinkedHashMap();
map.put("Version",2.0);
map.put("Parent-1",children1);
map.put("Parent-2",children2);      

//Style 1 - AUTO - Correct format for Parent-2
Yaml yaml1 = new Yaml();
String style1 = yaml1.dump(map);
System.out.println(style1);

//Style 2 - BLOCK - Correct format for Parent-1
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml2 = new Yaml(options);
String style2 = yaml2.dump(map);
System.out.println(style2);

The first option outputs this, which gives the correct format for Parent-2 but not for Parent-1:

Version: 2.0
Parent-1: {Criteria-1: 2, Criteria-2: 1}
Parent-2:
- [Criteria-1, Criteria-2, 1]

The second option outputs this, which gives the correct format for Parent-1 but not for Parent-2:

Version: 2.0
Parent-1:
  Criteria-1: 2
  Criteria-2: 1
Parent-2:
- - Criteria-1
  - Criteria-2
  - 1

The output I need is:

Version: 2.0
Parent-1:
  Criteria-1: 2
  Criteria-2: 1
Parent-2:
- [Criteria-1, Criteria-2, 1]

The actual file contains anchors and aliases, so I cannot dump the yaml in two times. Is there a way to custom which parts of the map should be FLOW and which should be BLOCK? Should I use another way to construct the map?


Solution

  • It does not look like you can specify a different flow style for mappings and sequences with DumperOptions.

    But what you can do, is override the Representer to enforce a non-default flow style for Mappings, like that:

    DumperOptions options = new DumperOptions();
    options.setDefaultFlowStyle(DumperOptions.FlowStyle.AUTO);
    
    Yaml yaml2 = new Yaml(new Representer() {
        @Override
        protected Node representMapping(Tag tag, Map<?, ?> mapping, Boolean flowStyle) {
            return super.representMapping(tag, mapping, false);
        }
    },options);
    String style2 = yaml2.dump(map);
    System.out.println(style2);
    

    which should give you the output you want:

    Version: 2.0
    Parent-1:
      Criteria-1: 2
      Criteria-2: 1
    Parent-2:
    - [Criteria-1, Criteria-2, 1]