Java SnakeYaml - 防止转储引用名称

标签 java snakeyaml

我使用以下方法将对象转换为 yaml 表示(例如,我可以打印到控制台)

@Nonnull
private String outputObject(@Nonnull final ObjectToPrint packageSchedule) {
    DumperOptions options = new DumperOptions();
    options.setAllowReadOnlyProperties(true);
    options.setPrettyFlow(true);
    return new Yaml(new Constructor(), new JodaTimeRepresenter(), options).dump(ObjectToPrint);
}

一切都很好,但是对于包含在 ObjectToPrint 结构中的某些对象,我得到了类似引用名称的东西,而不是真实的对象内容,例如。

!!com.blah.blah.ObjectToPrint
businessYears:
- businessYearMonths: 12
  ppiYear: &id001 {
    endDate: 30-06-2013,
    endYear: 2013,
    startDate: 01-07-2012,
    startYear: 2012
  }
  ppiPeriod:
    ppiYear: *id001
    endDate: 27-03-2014
    startDate: 21-06-2013
    units: 24.000
  number: 1

正如您从上面的示例中看到的,我打印了 ppiYear 对象(标记为 $id001)并且在 ppiPeriod 中使用了相同的对象> 但那里只打印引用名称,而不是对象内容。 每次我在我的结构中使用该对象时如何打印对象内容,我想将其转换为 yaml (ObjectToPrint)。 附言。最好完全不打印引用名称 (&id001),但这并不重要

最佳答案

这是因为你在不同的地方引用了同一个对象。为避免这种情况,您需要创建这些对象的副本。 Yaml 没有标志来关闭它,因为在循环引用的情况下你可能会陷入无限循环。 但是,您可以调整 Yaml 源代码以忽略双重引用:

查看 Serializer 行 ~170 方法 serializeNode:

...
 if ( this.serializedNodes.contains(node) ) {
    this.emmitter.emit( new AliasEvent( ... ) );
 } else {
    serializedNodes.add(node); // <== Replace with myHook(serializedNodes,node);
 ...

 void myHook(serializedNodes,node) {
    if ( node's class != myClass(es) to avoid ) {
        serializedNodes.add(node);
    }

如果您找到一种方法来避免 Yaml 将节点放入 serializedNodes 集合中,您的问题将得到解决,但是您的程序将在循环引用的情况下无限循环。

最好的解决方案是添加一个钩子(Hook),避免只注册您想要编写的类。

关于Java SnakeYaml - 防止转储引用名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18202548/

相关文章:

java - 堆初始化是什么意思?

java - 从 C++ 导出到 Eclipse 作为 Java 程序

c++ - 如何在yaml cpp中保留插入顺序

java - 使用 SnakeYaml 处理缺失字段

java - 如何将 Java 源文件的一部分转换为 Kotlin?

Java 8 foreach 将子对象添加到新列表

java - 加载多个 YAML 文件(使用@ConfigurationProperties?)

java - Checkstyle 和泛型

java - SnakeYaml dump函数用单引号写入