9

オブジェクトを表現に変換するために使用する次のメソッドがあります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)。PS。参照名をまったく出力しないのはいいことですが ( &id001)、それは重要ではありません

4

3 に答える 3

8

これは、異なる場所で同じオブジェクトを参照するためです。これを回避するには、それらのオブジェクトのコピーを作成する必要があります。循環参照の場合に無限ループに陥る可能性があるため、Yaml にはこれをオフにするフラグがありません。ただし、二重参照を無視するように Yaml ソース コードを微調整することもできます。

シリアライザ行 ~170 method 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 コレクションに入れるのを回避する方法を見つけた場合、問題は解決されますが、循環参照の場合、プログラムは無限にループします。

最善の解決策は、プレーンに記述したいクラスだけを登録しないようにするフックを追加することです。

于 2013-08-24T14:16:00.980 に答える
0

私がやってきた別の解決策は、可能であればio.circle代わりに使用することです。snake-yaml

スカラコード:

 private[this] def removeAnchors(configYaml: String): String = {
    val withoutAnchorsObj = io.circe.yaml.parser.parse(configYaml).valueOr(throw _)
    val withoutAnchorString = io.circe.yaml.Printer(dropNullKeys = true, mappingStyle = Printer.FlowStyle.Block).pretty(withoutAnchorsObj)
    logger.info(s"Removed Anchors from configYaml: $configYaml, result: $withoutAnchorString")
    withoutAnchorString
  }

build.sbt:

val circeVersion = "0.12.0"

libraryDependencies ++= Seq(
  "io.circe" %% "circe-yaml" % circeVersion,
  "io.circe" %% "circe-parser" % circeVersion,
)
于 2021-09-12T14:20:52.963 に答える