根据其 java 等效项 class (SnakeYaml) 对 YAML 文件条目进行排序
Order YAML file entries according to its java equivalent class (SnakeYaml)
我正在对 Java 中的两个 load/dump 数据使用 SnakeYaml。为此,我创建了一个带有字段的自定义 class,假设 class 看起来像这样:
public class Person {
private String name;
private String lastName;
private String address;
public Person() {
// Do nothing
}
// Getters and setters initialized for all the fields
}
现在,我想要的是,当我使用 SnakeYaml 将 Person 对象写入文件时,我希望字段按照它们在 class.
中定义的顺序排列
例如
name: Patrick
lastName: Star
Age : 42
问题是,对于更高级的示例,此排序是未实现的。目前我 writing/dumping 像下面这样的 yaml 文件:
Constructor struct = new Constructor(YamlIteratorModel.class);
Yaml yaml = new Yaml(struct);
try {
String path = "Some/File/Path/yamlfile.yaml";
FileWriter writer = new FileWriter(path);
yaml.dump(iteratorModel, writer);
} catch (IOExcepton e) {
// Do something
}
我还尝试过创建一个 Representer class 来扩展 Representer 并以类似的方式调用 Yaml 构造函数。这个取自另一个 post,它对我不起作用,因为它只按照我不完全确定的顺序对属性进行排序(现在找不到 link但如果我再次找到它会更新)..
public class ConfigurationModelRepresenter extends Representer {
/**
* Create object without specified dumper object
*/
public ConfigurationModelRepresenter() {
super();
}
/**
* Create object with dumper options
*
* @param options
*/
public ConfigurationModelRepresenter(DumperOptions options) {
super(options);
}
/** {@inheritDoc} */
@Override
protected Set<Property> getProperties(Class< ? extends Object> type) {
Set<Property> propertySet;
if (typeDefinitions.containsKey(type)) {
propertySet = typeDefinitions.get(type).getProperties();
} else {
propertySet = getPropertyUtils().getProperties(type);
}
List<Property> propsList = new ArrayList<>(propertySet);
Collections.sort(propsList, new BeanPropertyComparator());
return new LinkedHashSet<>(propsList);
}
class BeanPropertyComparator implements Comparator<Property> {
@Override
public int compare(Property p1, Property p2) {
// p1.getType().get
if (p1.getType().getCanonicalName().contains("util") && !p2.getType().getCanonicalName().contains("util")) {
return 1;
} else if (p2.getName().endsWith("Name") || p2.getName().equalsIgnoreCase("name")) {
return 1;
} else {
return -1;
}
}
}
}
SUMMARY:将对象转储到 YAML 文件(使用 SnakeYaml)时如何保持顺序,例如字段出现的顺序在自定义 class?
中定义
参见 this question,其中讨论了您无法通过反射获取已声明字段的行号。
再加上反射在no particular order中给你一个classes的字段,很明显在[=30=中观察声明字段的顺序是不可能的] 在运行时,因此您无法根据源代码中的 position/order 对 YAML 输出中的键进行排序,因为您不知道该顺序。
补救措施是将订单的知识传输到运行时。一些可能的方法可能是:
- 用定义生成的 YAML 密钥位置的
weight
注释每个字段(丑陋,因为您需要在字段上注释)。
- 通过解析 class' 定义从那里发现顺序来自动生成代码,并将其写入一些自动生成的源文件,然后使用其代码对 Representer 中的属性进行排序(此解决方案,同时避免膨胀原来class,非常复杂和精细。
- 在 Representer 中对字段顺序进行硬编码。这基本上是以前的解决方案,但没有自动生成。容易出错,因为每次更改 class 都必须调整 Representer。
我建议不要使用任何这些解决方案。 YAML 规范明确指出,密钥顺序不得传达内容信息,如果顺序对您很重要,那么您已经违反了 YAML 规范,应该切换到更能满足您需求的格式。
我正在对 Java 中的两个 load/dump 数据使用 SnakeYaml。为此,我创建了一个带有字段的自定义 class,假设 class 看起来像这样:
public class Person {
private String name;
private String lastName;
private String address;
public Person() {
// Do nothing
}
// Getters and setters initialized for all the fields
}
现在,我想要的是,当我使用 SnakeYaml 将 Person 对象写入文件时,我希望字段按照它们在 class.
中定义的顺序排列例如
name: Patrick
lastName: Star
Age : 42
问题是,对于更高级的示例,此排序是未实现的。目前我 writing/dumping 像下面这样的 yaml 文件:
Constructor struct = new Constructor(YamlIteratorModel.class);
Yaml yaml = new Yaml(struct);
try {
String path = "Some/File/Path/yamlfile.yaml";
FileWriter writer = new FileWriter(path);
yaml.dump(iteratorModel, writer);
} catch (IOExcepton e) {
// Do something
}
我还尝试过创建一个 Representer class 来扩展 Representer 并以类似的方式调用 Yaml 构造函数。这个取自另一个 post,它对我不起作用,因为它只按照我不完全确定的顺序对属性进行排序(现在找不到 link但如果我再次找到它会更新)..
public class ConfigurationModelRepresenter extends Representer {
/**
* Create object without specified dumper object
*/
public ConfigurationModelRepresenter() {
super();
}
/**
* Create object with dumper options
*
* @param options
*/
public ConfigurationModelRepresenter(DumperOptions options) {
super(options);
}
/** {@inheritDoc} */
@Override
protected Set<Property> getProperties(Class< ? extends Object> type) {
Set<Property> propertySet;
if (typeDefinitions.containsKey(type)) {
propertySet = typeDefinitions.get(type).getProperties();
} else {
propertySet = getPropertyUtils().getProperties(type);
}
List<Property> propsList = new ArrayList<>(propertySet);
Collections.sort(propsList, new BeanPropertyComparator());
return new LinkedHashSet<>(propsList);
}
class BeanPropertyComparator implements Comparator<Property> {
@Override
public int compare(Property p1, Property p2) {
// p1.getType().get
if (p1.getType().getCanonicalName().contains("util") && !p2.getType().getCanonicalName().contains("util")) {
return 1;
} else if (p2.getName().endsWith("Name") || p2.getName().equalsIgnoreCase("name")) {
return 1;
} else {
return -1;
}
}
}
}
SUMMARY:将对象转储到 YAML 文件(使用 SnakeYaml)时如何保持顺序,例如字段出现的顺序在自定义 class?
中定义参见 this question,其中讨论了您无法通过反射获取已声明字段的行号。
再加上反射在no particular order中给你一个classes的字段,很明显在[=30=中观察声明字段的顺序是不可能的] 在运行时,因此您无法根据源代码中的 position/order 对 YAML 输出中的键进行排序,因为您不知道该顺序。
补救措施是将订单的知识传输到运行时。一些可能的方法可能是:
- 用定义生成的 YAML 密钥位置的
weight
注释每个字段(丑陋,因为您需要在字段上注释)。 - 通过解析 class' 定义从那里发现顺序来自动生成代码,并将其写入一些自动生成的源文件,然后使用其代码对 Representer 中的属性进行排序(此解决方案,同时避免膨胀原来class,非常复杂和精细。
- 在 Representer 中对字段顺序进行硬编码。这基本上是以前的解决方案,但没有自动生成。容易出错,因为每次更改 class 都必须调整 Representer。
我建议不要使用任何这些解决方案。 YAML 规范明确指出,密钥顺序不得传达内容信息,如果顺序对您很重要,那么您已经违反了 YAML 规范,应该切换到更能满足您需求的格式。