Странные персонажи при сбросе объектов в SnakeYaml

Я использую 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 (// ЭТО комментарий СТРОКИ), но вместо этого получал следующее:

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

Для любого метода, как я могу

(1) Очистить символы |- и |2- от сброса? (с ScalarStyle.LITERAL)

or

(2) Убрать одинарные кавычки из печати? (без ScalarStyle.LITERAL)

Я ценю любые советы, которые мне могут дать по этому поводу ..

Спасибо заранее!


person wood    schedule 19.05.2021    source источник
comment
Попробуйте изменить setDefaultFlowStyle на DumperOptions.FlowStyle.BLOCK   -  person Layne Bernardo    schedule 19.05.2021
comment
@LayneBernardo Изменение FlowStyle на BLOCK по-прежнему вызывает обе проблемы :(   -  person wood    schedule 19.05.2021


Ответы (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 дампер снова должен заключить строку в кавычки, потому что она содержит пробелы, двойные кавычки и двоеточие, все из которых являются специальными символами YAML.

Очевидно, вы не хотите этого делать. Вы должны понимать, что дампер YAML принимает структуру данных и сериализует ее как YAML. Итак, что вам нужно сделать, это предоставить ему нужную структуру данных:

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

Также замените DumperOptions.ScalarStyle.LITERAL на DumperOptions.FlowStyle.BLOCK. Это даст вам желаемую структуру, хотя и без двойных кавычек. Это не имеет значения, поскольку результирующий YAML эквивалентен.

Чтобы принудительно цитировать эти скаляры, см. этот ответ.

person flyx    schedule 19.05.2021
comment
Спасибо, что нашли время все объяснить! - person wood; 20.05.2021