首页 > 解决方案 > 如何使用 SnakeYaml 对 YAML 中的节点进行排序?

问题描述

我正在使用snakeyaml 将java 对象解析为YAML,并且snakeyaml 是按字母顺序排列的。

我想使用 java 对象中定义的节点顺序。

前任:

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)

如何在 YAML 中保留订单?

标签: javasnakeyaml

解决方案


排序顺序来自 PropertyUtils.createPropertySet,它使用的是 TreeSet。

我找到了一种方法来覆盖它扩展代表:


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);
  }
}

然后在您的代码中使用:

Representer representer = new CustomRepresenter();

推荐阅读