2

I have a YAML string where one of the attributes looks like this:

 description: |
    this is my description  //imagine there's a space after description
    this is my description in the second line

In my Java code I read it into a JsonNode like this:

JsonNode node = new YamlMapper().readTree(yamlString);

I then do some changes to it and write it back to a string like this:

new YamlMapper().writeValueAsString(node))

The new string now looks like this:

"this is my description \nthis is my description in the second line\n"

So now in the YAML file you can see the added quotes + the new line character (\n) and everything is in one line. I expect it to return the original YAML like the one above.

This is how my YAML object mapper is configured:

 new ObjectMapper(
        new YAMLFactory()
          .disable(YAMLGenerator.Feature.MINIMIZE_QUOTES))
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

If I remove the space after description in the original YAML, it works just fine

kimi1990mp
  • 101
  • 1
  • 13
  • why disable `YAMLGenerator.Feature.MINIMIZE_QUOTES` ? since version 2.9, if you enable this feature, jackson will auto enable `LITERAL_BLOCK_STYLE` feature, which serializes multiline string using "|-" style – AssKicker Apr 21 '22 at 11:56

2 Answers2

2

To serialize multiline text using jackson. Jackson introduced a new flag YAMLGenerator.Feature.LITERAL_BLOCK_STYLE since version 2.9, which can be turned on as:

new ObjectMapper(
    new YAMLFactory().enable(YAMLGenerator.Feature.LITERAL_BLOCK_STYLE)
).writeValueAsString(new HashMap<String, String>(){{
    put("key", "test1\ntest2\ntest3");
}});

The output won't be wrapped with quotes:

---
key: |-
  test1
  test2
  test3

Note there is a few differences between "block scalars": |, |-, >..., you can check out at https://yaml-multiline.info/

AssKicker
  • 124
  • 3
0

Jackson's API is too high level to control the output in detail. You can use SnakeYAML directly (which is used by Jackson under the hood), but you need to go down to the node or event level of the API to control node style in the output.

See also: I want to load a YAML file, possibly edit the data, and then dump it again. How can I preserve formatting?

This answer shows general usage of SnakeYAML's event API to keep formatting; of course it's harder to do changes on a stream of events. You might instead want to work on the node graph, this answer has some example code showing how to load YAML to a node graph, process it, and write it back again.

flyx
  • 35,506
  • 7
  • 89
  • 126
  • 1
    Right now, I need to make it work using Jackson's api. I edited the question. Seems like the issue occurs only when there's a space at the end of one of the lines, right before the new line. Can you check the edited question and let me know if you have any idea how I can handle it? – kimi1990mp Jan 29 '21 at 13:29
  • You already used all settings available via Jackson's API. There is nothing else you can do to manipulate SnakeYAML's decision in Jackson's backend about how to serialize the string, apart from changing the string's content (like e.g. removing a space). The only other thing you can do is to drop the restraint that the string must be serialized as block scalar – the quoted scalar you get is semantically equivalent to what you had before and as I explain in the linked question, if you do have a strict requirement about serailization details, YAML is the wrong tool for you. – flyx Jan 29 '21 at 13:42
  • @kimi1990mp the line at the end of the line was my issue too... Strange that. – Austin Poole Sep 08 '21 at 03:21