Странни знаци при изхвърляне на обекти в 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 dumper, сякаш е обикновен изходен поток. Какво мислите, че прави самосвалът YAML? Ако просто изпише низовете, които му давате, няма да има смисъл да го използвате.

Сега да видим какво всъщност се случва:

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

Тук вие молите YAML dumper да изхвърли единичен низ, 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 dumper взема структура от данни и я сериализира като 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