【问题标题】:Weird characters when dumping objects in SnakeYaml在 SnakeYaml 中转储对象时出现奇怪的字符
【发布时间】:2021-05-19 00:31:12
【问题描述】:

我正在使用 SnakeYaml 和 Java 尝试写入 yaml 文件,但在转储过程中我看到奇怪的字符...

这是我所拥有的:

PrintWriter writer = new PrintWriter(new File("./output.yaml"));

DumperOptions mapOptions = new DumperOptions();
mapOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.AUTO);
mapOptions.setDefaultScalarStyle(DumperOptions.ScalarStyle.LITERAL); // THIS LINE
mapOptions.setPrettyFlow(true);

Yaml mapYaml = new Yaml(mapOptions);

mapYaml.dump("mapping:", writer);
mapYaml.dump("  \"table\":" + "\"" + map.get(tableName) + "\"", writer);

我的期待:

mapping:
  "table": "tableName"

我得到的输出:

|- 
  mapping:
|2- 
    "table": "tableName"

我也尝试不使用 DumperOptions.ScalarStyle.Literal 行(// THIS LINE 注释),但我得到的是这个:

'mapping:'
'  "table": "tableName"'

对于任何一种方法,我该怎么做

(1) 清除被转储的|-|2- 符号? (使用 ScalarStyle.LITERAL)

(2) 清除打印中的单引号? (没有 ScalarStyle.LITERAL)

感谢任何人对此提供的任何指导..

提前谢谢你!

【问题讨论】:

  • 尝试将 setDefaultFlowStyle 更改为 DumperOptions.FlowStyle.BLOCK
  • @LayneBernardo 将 FlowStyle 更改为 BLOCK 仍然存在这两个问题:(

标签: java yaml string-formatting snakeyaml


【解决方案1】:

您正在使用 YAML 转储程序,就像它是一个简单的输出流一样。你认为 YAML 转储程序有什么作用?如果它只是写出你给它的字符串,那么使用它是没有意义的。

现在让我们看看实际发生了什么:

mapYaml.dump("mapping:", writer);

在这里,您要求 YAML 转储程序转储单个字符串 mapping:。如果您提供DumperOptions.ScalarStyle.LITERAL,YAML 转储程序将完全按照您的要求将其转储为文字块标量:

|- 
  mapping:

字符| 开始一个文字块标量。以下所有缩进较多的行将按字面意思阅读,无需任何处理。这将使这个 YAML 加载为字符串 mapping:,就像您请求的那样。 | 后面的 - 告诉文字块标量不要在值中包含最后的换行符。

如果您忽略 DumperOptions.ScalarStyle.LITERAL,YAML 转储程序需要适应 YAML 中的冒号是特殊字符这一事实。由于您明确要求转储程序将其作为字符串的一部分,因此转储程序需要引用该字符串:

'mapping:'

你刚才看到的 YAML 文档是完整的。对 dump 的每次调用都会发出一个完整的 YAML 文档,您不能只是将它们连接起来并期望它们合并到一个 YAML 文档中。所以调用 dump 两次并不是你真正想要的。

现在让我们讨论第二行:

mapYaml.dump("  \"table\":" + "\"" + map.get(tableName) + "\"", writer);

输出中发生的情况与第一种情况大致相同。文字块标量中的2 表示恰好两个空格被读取为缩进。这会导致开头的额外两个空格被读取为内容,就像您请求的那样。没有DumperOptions.ScalarStyle.LITERAL,dumper 再次需要引用字符串,因为它包含空格、双引号和冒号,这些都是特殊的 YAML 字符。

显然,这些都不是您想要做的。您需要了解 YAML 转储程序采用数据结构并将其序列化为 YAML。所以你需要做的就是给它你想要的数据结构:

mapYaml.dump(Map.of("mapping", Map.of("table", map.get(tableName)));

还将DumperOptions.ScalarStyle.LITERAL 替换为DumperOptions.FlowStyle.BLOCK。这将为您提供所需的结构,尽管没有双引号。这无关紧要,因为生成的 YAML 是等效的。

要强制引用这些标量,请参阅 this answer

【讨论】:

  • 感谢您花时间解释一切!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多