How to order nodes in YAML with SnakeYaml?

Viewed 759

I am parsing a java object into YAML using snakeyaml and snakeyaml is ordering alphabetically.

I want to use the order of nodes that are defined in the java object.

ex:

ClassB
  String name;
  String address;
  String description;
  ClassA classa;

This prints as 
classb
  address : ..
  classa: ..
  description: ..
  name: ..  

Expected Output

classb
  name: ..  
  address : ..
  description: ..
  classa: ..


Code: 

Representer representer = new Representer();
representer.getPropertyUtils().setSkipMissingProperties(true);

DumperOptions dumperOptions = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStype.BLOCK);
options.setPrettyFlow(true);

Yaml yaml = new Yaml (new Constructor(ClassC.class, representer, options)

How do i retain the order in YAML?

1 Answers

The sort order comes from PropertyUtils.createPropertySet, it is using a TreeSet.

I found a way to override it extending Representer:


import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;

import org.yaml.snakeyaml.introspector.*;
import org.yaml.snakeyaml.nodes.*;
import org.yaml.snakeyaml.representer.Representer;

public class CustomRepresenter extends Representer {

  public CustomRepresenter() {
    super();
    PropertyUtils propUtil = new PropertyUtils() {
      @Override
      protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bAccess) {
        return getPropertiesMap(type, bAccess).values().stream().sequential()
            .filter(prop -> prop.isReadable() && (isAllowReadOnlyProperties() || prop.isWritable()))
            .collect(Collectors.toCollection(LinkedHashSet::new));
      }
    };
    setPropertyUtils(propUtil);
  }
}

then use at your code as:

Representer representer = new CustomRepresenter();
Related