spring 使用snakeyaml将动态ScalarStyle应用于某些节点

hs1rzwqc  于 2023-01-08  发布在  Spring
关注(0)|答案(1)|浏览(151)

我需要根据负载的节点将复杂的负载解析为带双引号或纯标量样式的yaml
我希望得到的结果是这样的:
'

config:
  zzh: true
  zzh-special-config:
    expressions:
    - expression: "(#{deliveryCity} IN ['MADRID', 'BARNA'] && (#{channel} IN ['1'] || (#{domain} IN ['core'] && (#{environment} IN ['des,test'] || #{layer} IN ['composite']))))"
      value: false
      description: "my-description"

'
如果使用以下配置:
'

public static Yaml getYamlMapper() {
final LoaderOptions loaderOptions = new LoaderOptions();
loaderOptions.setAllowDuplicateKeys(false);
loaderOptions.setMaxAliasesForCollections(Integer.MAX_VALUE);
loaderOptions.setAllowRecursiveKeys(true);

final DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setIndent(2);
dumperOptions.setPrettyFlow(true);
dumperOptions.setDefaultFlowStyle(FlowStyle.BLOCK);
dumperOptions.setSplitLines(false);
dumperOptions.setDefaultScalarStyle(ScalarStyle.PLAIN);
return new Yaml(new Constructor(), new Representer(), dumperOptions, loaderOptions, new Resolver());
}

'
表达式分析不正确:'

config:
  zzh: true
  zzh-special-config:
    expressions:
    - expression: '(#{deliveryCity} IN [''MADRID'', ''BARNA''] && (#{channel} IN [''1''] || (#{domain} IN [''core''] && (#{environment} IN [''des,test''] || #{layer} IN [''composite'']))))'
      value: false
      description: my-description

'
但是,如果我以这种方式更改Yaml配置:
'

dumperOptions.setDefaultScalarStyle(ScalarStyle.DOUBLE_QUOTED);

'
布尔值和整数值分解(例如:!!bool "true")....而且它还在键中加上了双引号:/
'

"config":
  "zzh": !!bool "true"
  "zzh-special-config":
    "expressions":
    - "expression": "(#{deliveryCity} IN ['MADRID', 'BARNA'] && (#{channel} IN ['1'] || (#{domain} IN ['core'] && (#{environment} IN ['des,test'] || #{layer} IN ['composite']))))"
      "value": !!bool "false"
      "description": "my-description"

'
正如您所看到的,当我修复某个东西时,其他东西也会损坏...因此,理想的情况是仅在所有expression节点中执行此操作(例如:配置zzh-amiga-配置表达式[].表达式)
我想我可以使用ScalarNode对象,但我不知道如何实现我的目的,特别是考虑到表达式列表可能出现在任何节点下,因此必须使用某种通配符...
有人能帮帮我吗?
先谢了!

pgky5nke

pgky5nke1#

最后,我认为这段代码做的把戏,我一直在寻找:

public static Yaml getYamlMapper() {
    final LoaderOptions loaderOptions = new LoaderOptions();
    loaderOptions.setAllowDuplicateKeys(false);
    loaderOptions.setMaxAliasesForCollections(Integer.MAX_VALUE);
    loaderOptions.setAllowRecursiveKeys(true);

    final DumperOptions dumperOptions = new DumperOptions();
    dumperOptions.setIndent(2);
    dumperOptions.setPrettyFlow(true);
    dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
    dumperOptions.setSplitLines(false);

    return new Yaml(new Constructor(), new ComplexDataExpressionRepresenter(), dumperOptions, loaderOptions, new Resolver());
  }

  /**
   * Special representer able to deal with expressions.
   */
  static class ComplexDataExpressionRepresenter extends Representer {

    public ComplexDataExpressionRepresenter() {
      this.representers.put(String.class, new RepresentQuotedString());
    }

    private class RepresentQuotedString implements Represent {

      public Node representData(final Object data) {
        final String valueToString = data.toString();
        if (valueToString.contains("#{")) {
          // This do the trick to expressions and maybe also to another properties but is ok.
          return ComplexDataExpressionRepresenter.this.representScalar(Tag.STR, valueToString, ScalarStyle.DOUBLE_QUOTED);
        }
        return ComplexDataExpressionRepresenter.this.representScalar(Tag.STR, valueToString, ScalarStyle.PLAIN);
      }
    }
  }

最好的问候!

相关问题